Exemplo n.º 1
0
int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree,
                                       const knot_dname_t *owner,
                                       knot_node_t **found,
                                       knot_node_t **previous)
{
	if (tree == NULL || owner == NULL || found == NULL
	    || previous == NULL) {
		return KNOT_EINVAL;
	}

	char lf[DNAME_LFT_MAXLEN];
	dname_lf(lf, owner, sizeof(lf));

	value_t *fval = NULL;
	int ret = hattrie_find_leq(tree, lf+1, *lf, &fval);
	if (fval) *found = (knot_node_t *)(*fval);
	int exact_match = 0;
	if (ret == 0) {
		*previous = knot_node_get_previous(*found);
		exact_match = 1;
	} else if (ret < 0) {
		*previous = *found;
		*found = NULL;
	} else if (ret > 0) {
		/* node is before first node in the trie */
		*previous = knot_node_get_previous(*found);
		/* left of leftmost node is the rightmost node */
		*found = NULL;
	}

	/* Check if previous node is not an empty non-terminal. */
	if (knot_node_rrset_count(*previous) == 0) {
		*previous = knot_node_get_previous(*previous);
	}

dbg_zone_exec_detail(
		char *name = knot_dname_to_str(owner);
		char *name_f = (*found != NULL)
			? knot_dname_to_str(knot_node_owner(*found))
			: "none";

		dbg_zone_detail("Searched for owner %s in zone tree.\n",
				name);
		dbg_zone_detail("Exact match: %d\n", exact_match);
		dbg_zone_detail("Found node: %p: %s.\n", *found, name_f);
		dbg_zone_detail("Previous node: %p.\n", *previous);

		free(name);
		if (*found != NULL) {
			free(name_f);
		}
);
Exemplo n.º 2
0
static void ztree_iter_data(knot_node_t **node, void *data)
{
	struct ztree_iter *it = (struct ztree_iter*)data;
	knot_dname_t *owner = (*node)->owner;
	if (owner != ORDER[it->i]) {
		it->ret = KNOT_ERROR;
		char *exp_s = knot_dname_to_str(ORDER[it->i]);
		char *owner_s = knot_dname_to_str(owner);
		diag("ztree: at index: %u expected '%s' got '%s'\n", it->i, exp_s, owner_s);
		free(exp_s);
		free(owner_s);
	}
	++it->i;
}
Exemplo n.º 3
0
static int knot_tsig_check_key(const knot_rrset_t *tsig_rr,
                               const knot_tsig_key_t *tsig_key)
{
	if (tsig_rr == NULL || tsig_key == NULL) {
		return KNOT_EINVAL;
	}

	const knot_dname_t *tsig_name = tsig_rr->owner;
	if (!tsig_name) {
		return KNOT_EMALF;
	}

	char *name = knot_dname_to_str(tsig_name);
	if (!name) {
		return KNOT_EMALF;
	}

	if (knot_dname_cmp(tsig_name, tsig_key->name) != 0) {
		/*!< \todo which error. */
		dbg_tsig("TSIG: unknown key: %s\n", name);
		free(name);
		return KNOT_TSIG_EBADKEY;
	}

	free(name);
	return KNOT_EOK;
}
Exemplo n.º 4
0
static int yp_dname_to_txt(
	BIN_TXT_PARAMS)
{
	char *name = knot_dname_to_str(txt, bin, *txt_len);
	if (name == NULL) {
		return KNOT_EINVAL;
	}

	*txt_len = strlen(txt);

	return KNOT_EOK;
}
Exemplo n.º 5
0
/** Retrieve hint list. */
static int pack_hint(const char *k, void *v, void *baton)
{
	char nsname_str[KNOT_DNAME_MAXLEN] = {'\0'};
	knot_dname_to_str(nsname_str, (const uint8_t *)k, sizeof(nsname_str));
	JsonNode *root_node = baton;
	JsonNode *addr_list = pack_addrs((pack_t *)v);
	if (!addr_list) {
		return kr_error(ENOMEM);
	}
	json_append_member(root_node, nsname_str, addr_list);
	return kr_ok();
}
Exemplo n.º 6
0
/*!
 * \brief Tries to add RRSet to the response.
 *
 * This function tries to convert the RRSet to wire format and add it to the
 * wire format of the response and if successful, adds the RRSet to the given
 * list (and updates its size). If the RRSet did not fit into the available
 * space (\a max_size), it is omitted as a whole and the TC bit may be set
 * (according to \a tc).
 *
 * \param rrsets Lists of RRSets to which this RRSet should be added.
 * \param rrset_count Number of RRSets in the list.
 * \param resp Response structure where the RRSet should be added.
 * \param max_size Maximum available space in wire format of the response.
 * \param rrset RRSet to add.
 * \param tc Set to <> 0 if omitting the RRSet should cause the TC bit to be
 *           set in the response.
 *
 * \return Count of RRs added to the response or KNOT_ESPACE if the RRSet did
 *         not fit in the available space.
 */
static int knot_response_try_add_rrset(const knot_rrset_t **rrsets,
                                        short *rrset_count,
                                        knot_packet_t *resp,
                                        size_t max_size,
                                        const knot_rrset_t *rrset, int tc)
{
	//short size = knot_response_rrset_size(rrset, &resp->compression);

dbg_response_exec(
	char *name = knot_dname_to_str(rrset->owner);
	dbg_response_verb("\nAdding RRSet with owner %s and type %u: \n",
	                  name, rrset->type);
	free(name);
);
Exemplo n.º 7
0
Arquivo: conf.c Projeto: idtek/knot
static int str_zone(
	const knot_dname_t *zone,
	char *buff,
	size_t buff_len)
{
	if (knot_dname_to_str(buff, zone, buff_len) == NULL) {
		return KNOT_EINVAL;
	}

	// Replace possible slashes with underscores.
	replace_slashes(buff, true);

	return KNOT_EOK;
}
Exemplo n.º 8
0
void knot_zone_deep_free(knot_zone_t **zone)
{
	if (zone == NULL || *zone == NULL) {
		return;
	}

	if ((*zone)->contents
	    && !knot_zone_contents_gen_is_old((*zone)->contents)) {
		// zone is in the middle of an update, report
		dbg_zone("Destroying zone that is in the middle of an "
		         "update.\n");
	}

dbg_zone_exec(
	char *name = knot_dname_to_str((*zone)->name);
	dbg_zone("Destroying zone %p, name: %s.\n", *zone, name);
	free(name);
);
Exemplo n.º 9
0
Arquivo: conf.c Projeto: idtek/knot
static int str_char(
	const knot_dname_t *zone,
	char *buff,
	size_t buff_len,
	uint8_t index1,
	uint8_t index2)
{
	if (knot_dname_to_str(buff, zone, buff_len) == NULL) {
		return KNOT_EINVAL;
	}

	// Remove the trailing dot.
	size_t zone_len = strlen(buff);
	assert(zone_len > 0);
	buff[zone_len--] = '\0';

	// Get the block length.
	size_t len = index2 - index1 + 1;

	// Check for out of scope block.
	if (index1 >= zone_len) {
		buff[0] = '\0';
		return KNOT_EOK;
	}
	// Check for partial block.
	if (index2 >= zone_len) {
		len = zone_len - index1;
	}

	// Copy the block.
	memmove(buff, buff + index1, len);
	buff[len] = '\0';

	// Replace possible slashes with underscores.
	replace_slashes(buff, false);

	return KNOT_EOK;
}
Exemplo n.º 10
0
static int rosedb_list(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
{
	MDB_cursor *cursor = cursor_acquire(txn, cache->dbi);
	MDB_val key, data;
	char dname_str[KNOT_DNAME_MAXLEN] = {'\0'};
	char type_str[16] = { '\0' };

	int ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
	while (ret == 0) {
		struct entry entry;
		unpack_entry(&data, &entry);
		knot_dname_to_str(dname_str, key.mv_data, sizeof(dname_str));
		knot_rrtype_to_string(entry.data.type, type_str, sizeof(type_str));
		printf("%s\t%s RDATA=%zuB\t%s\t%s\n", dname_str, type_str,
		       knot_rdataset_size(&entry.data.rrs), entry.threat_code, entry.syslog_ip);

		ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT);
	}

	cursor_release(cursor);

	return KNOT_EOK;
}
Exemplo n.º 11
0
static int rosedb_log_message(char *stream, size_t *maxlen, knot_pkt_t *pkt,
                              const char *threat_code, struct query_data *qdata)
{
	char dname_buf[KNOT_DNAME_MAXLEN] = {'\0'};
	struct sockaddr_storage addr;
	socklen_t addr_len = sizeof(addr);
	time_t now = time(NULL);
	struct tm tm;
	gmtime_r(&now, &tm);

	/* Field 1 Timestamp (UTC). */
	STREAM_WRITE(stream, maxlen, strftime, "%Y-%m-%d %H:%M:%S\t", &tm);

	/* Field 2/3 Remote, local address. */
	const struct sockaddr *remote = (const struct sockaddr *)qdata->param->remote;
	memcpy(&addr, remote, sockaddr_len(remote));
	int client_port = sockaddr_port(&addr);
	sockaddr_port_set(&addr, 0);
	STREAM_WRITE(stream, maxlen, sockaddr_tostr, &addr);
	STREAM_WRITE(stream, maxlen, snprintf, "\t");
	getsockname(qdata->param->socket, (struct sockaddr *)&addr, &addr_len);
	int server_port = sockaddr_port(&addr);
	sockaddr_port_set(&addr, 0);
	STREAM_WRITE(stream, maxlen, sockaddr_tostr, &addr);
	STREAM_WRITE(stream, maxlen, snprintf, "\t");

	/* Field 4/5 Local, remote port. */
	STREAM_WRITE(stream, maxlen, snprintf, "%d\t%d\t", client_port, server_port);

	/* Field 6 Threat ID. */
	STREAM_WRITE(stream, maxlen, snprintf, "%s\t", threat_code);

	/* Field 7 - 13 NULL */
	STREAM_WRITE(stream, maxlen, snprintf, "\t\t\t\t\t\t\t");

	/* Field 14 QNAME */
	knot_dname_to_str(dname_buf, knot_pkt_qname(qdata->query), sizeof(dname_buf));
	STREAM_WRITE(stream, maxlen, snprintf, "%s\t", dname_buf);

	/* Field 15 Resolution (0 = local, 1 = lookup)*/
	STREAM_WRITE(stream, maxlen, snprintf, "0\t");

	/* Field 16 RDATA.
	 * - Return randomly RDATA in the answer section (probabilistic rotation).
	 * - Empty if no answer.
	 */
	const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER);
	if (ans->count > 0) {
		const knot_rrset_t *rr = &ans->rr[knot_random_uint16_t() % ans->count];
		int ret = knot_rrset_txt_dump_data(rr, 0, stream, *maxlen, &KNOT_DUMP_STYLE_DEFAULT);
		if (ret < 0) {
			return ret;
		}
		stream_skip(&stream, maxlen, ret);
	}
	STREAM_WRITE(stream, maxlen, snprintf, "\t");

	/* Field 17 Connection type. */
	STREAM_WRITE(stream, maxlen, snprintf, "%s\t",
	             net_is_connected(qdata->param->socket) ? "TCP" : "UDP");

	/* Field 18 Query type. */
	char type_str[16] = { '\0' };
	knot_rrtype_to_string(knot_pkt_qtype(qdata->query), type_str, sizeof(type_str));
	STREAM_WRITE(stream, maxlen, snprintf, "%s\t", type_str);

	/* Field 19 First authority. */
	const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
	if (ns->count > 0 && ns->rr[0].type == KNOT_RRTYPE_NS) {
		const knot_dname_t *label = knot_ns_name(&ns->rr[0].rrs, 0);
		memset(dname_buf, 0, sizeof(dname_buf));
		memcpy(dname_buf, label + 1, *label);
		STREAM_WRITE(stream, maxlen, snprintf, "%s", dname_buf);
	}

	return KNOT_EOK;
}
Exemplo n.º 12
0
int notify_process_request(knot_nameserver_t *ns,
                           knot_packet_t *notify,
                           sockaddr_t *from,
                           uint8_t *buffer, size_t *size)
{
	/*! \todo Most of this function is identical to xfrin_transfer_needed()
	 *        - it will be fine to merge the code somehow.
	 */

	if (notify == NULL || ns == NULL || buffer == NULL
	    || size == NULL || from == NULL) {
		dbg_notify("notify: invalid parameters for %s()\n",
		           "notify_process_request");
		return KNOT_EINVAL;
	}

	int ret = KNOT_EOK;

	dbg_notify("notify: parsing rest of the packet\n");
	if (notify->parsed < notify->size) {
		if (knot_packet_parse_rest(notify, 0) != KNOT_EOK) {
			dbg_notify("notify: failed to parse NOTIFY query\n");
			knot_ns_error_response_from_query(ns, notify,
			                                  KNOT_RCODE_FORMERR,
			                                  buffer, size);
			return KNOT_EOK;
		}
	}

	// check if it makes sense - if the QTYPE is SOA
	if (knot_packet_qtype(notify) != KNOT_RRTYPE_SOA) {
		// send back FORMERR
		knot_ns_error_response_from_query(ns, notify,
		                                  KNOT_RCODE_FORMERR, buffer,
		                                  size);
		return KNOT_EOK;
	}

	// create NOTIFY response
	dbg_notify("notify: creating response\n");
	ret = notify_create_response(notify, buffer, size);
	if (ret != KNOT_EOK) {
		dbg_notify("notify: failed to create NOTIFY response\n");
		knot_ns_error_response_from_query(ns, notify,
		                                  KNOT_RCODE_SERVFAIL, buffer,
		                                  size);
		return KNOT_EOK;
	}

	/* Process notification. */
	ret = KNOT_ENOZONE;
	unsigned serial = 0;
	const knot_dname_t *qname = knot_packet_qname(notify);
	rcu_read_lock(); /* z */
	const knot_zone_t *z = knot_zonedb_find_zone_for_name(ns->zone_db, qname);
	if (z != NULL) {
		ret = notify_check_and_schedule(ns, z, from);
		const knot_rrset_t *soa_rr = NULL;
		soa_rr = knot_packet_answer_rrset(notify, 0);
		if (soa_rr && knot_rrset_type(soa_rr) == KNOT_RRTYPE_SOA) {
			serial = knot_rrset_rdata_soa_serial(soa_rr);
		}
	}
	rcu_read_unlock();

	int rcode = KNOT_RCODE_NOERROR;
	switch (ret) {
	case KNOT_ENOZONE: rcode = KNOT_RCODE_NOTAUTH; break;
	case KNOT_EACCES:  rcode = KNOT_RCODE_REFUSED; break;
	default: break;
	}

	/* Format resulting log message. */
	char *qstr = knot_dname_to_str(qname);
	char *fromstr = xfr_remote_str(from, NULL);
	if (rcode != KNOT_RCODE_NOERROR) {
		knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_REFUSED,
		                                  buffer, size);
		log_server_warning(NOTIFY_MSG "%s\n", qstr, fromstr, knot_strerror(ret));
		ret = KNOT_EOK; /* Send response. */
	} else {
		log_server_info(NOTIFY_MSG NOTIFY_XMSG "\n", qstr, fromstr, serial);
	}
	free(qstr);
	free(fromstr);

	return ret;
}