Skip to content
Snippets Groups Projects
nsrep.h 4.66 KiB
Newer Older
/*  Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
#include <netinet/in.h>
#include <sys/socket.h>
Marek Vavruša's avatar
Marek Vavruša committed
#include <libknot/dname.h>
#include "lib/defines.h"
#include "lib/generic/map.h"
#include "lib/generic/lru.h"
Marek Vavruša's avatar
Marek Vavruša committed
/** 
  * NS RTT score (special values).
  * @note RTT is measured in milliseconds.
Marek Vavruša's avatar
Marek Vavruša committed
  */
	KR_NS_MAX_SCORE = KR_CONN_RTT_MAX,
	KR_NS_TIMEOUT   = (95 * KR_NS_MAX_SCORE) / 100,
	KR_NS_LONG      = (3 * KR_NS_TIMEOUT) / 4,
	KR_NS_UNKNOWN   = KR_NS_TIMEOUT / 2,
	KR_NS_PENALTY   = 100,
/**
 * NS QoS flags.
 */
enum kr_ns_rep {
	KR_NS_NOIP4  = 1 << 0, /**< NS has no IPv4 */
	KR_NS_NOIP6  = 1 << 1, /**< NS has no IPv6 */
	KR_NS_NOEDNS = 1 << 2  /**< NS has no EDNS support */
};

/**
 * NS RTT update modes.
 */
enum kr_ns_update_mode {
	KR_NS_UPDATE = 0, /**< Update as smooth over last two measurements */
	KR_NS_RESET,      /**< Set to given value */
	KR_NS_ADD,        /**< Increment current value */
	KR_NS_MAX         /**< Set to maximum of current/proposed value. */
/**
 * NS reputation/QoS tracking.
 */
typedef lru_t(unsigned) kr_nsrep_lru_t;
/* Maximum count of addresses probed in one go (last is left empty) */
#define KR_NSREP_MAXADDR 4
Marek Vavruša's avatar
Marek Vavruša committed
/**
 * Name server representation.
 * Contains extra information about the name server, e.g. score
 * or other metadata.
 */
struct kr_nsrep
{
	unsigned score;                  /**< NS score */
	unsigned reputation;             /**< NS reputation */
	const knot_dname_t *name;        /**< NS name */
	struct kr_context *ctx;          /**< Resolution context */
	union {
		struct sockaddr ip;
		struct sockaddr_in ip4;
		struct sockaddr_in6 ip6;
	} addr[KR_NSREP_MAXADDR];        /**< NS address(es) */
/** @internal Address bytes for given family. */
#define kr_nsrep_inaddr(addr) \
	((addr).ip.sa_family == AF_INET ? (void *)&((addr).ip4.sin_addr) : (void *)&((addr).ip6.sin6_addr))
/** @internal Address length for given family. */
#define kr_nsrep_inaddr_len(addr) \
	((addr).ip.sa_family == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr))

/**
 * Set given NS address.
 * @param  qry      updated query
 * @param  index    index of the updated target
 * @param  addr     address bytes (struct in_addr or struct in6_addr)
 * @param  addr_len address bytes length (type will be derived from this)
 * @param  port     address port (if <= 0, 53 will be used)
 * @return          0 or an error code
 */
int kr_nsrep_set(struct kr_query *qry, size_t index, uint8_t *addr, size_t addr_len, int port);
/**
 * Elect best nameserver/address pair from the nsset.
 * @param  qry          updated query
 * @param  ctx          resolution context
 * @return              0 or an error code
int kr_nsrep_elect(struct kr_query *qry, struct kr_context *ctx);
/**
 * Elect best nameserver/address pair from the nsset.
 * @param  qry          updated query
 * @param  ctx          resolution context
 * @return              0 or an error code
 */
int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx);

 * Update NS address RTT information.
 * @brief In KR_NS_UPDATE mode reputation is smoothed over last N measurements.
 * 
 * @param  ns           updated NS representation
 * @param  addr         chosen address (NULL for first)
 * @param  score        new score (i.e. RTT), see enum kr_ns_score
 * @param  umode        update mode (KR_NS_UPDATE or KR_NS_RESET or KR_NS_ADD)
 * @return              0 on success, error code on failure
 */
int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
			unsigned score, kr_nsrep_lru_t *cache, int umode);
 * Update NSSET reputation information.
 * 
 * @param  ns           updated NS representation
 * @param  reputation   combined reputation flags, see enum kr_ns_rep
 * @param  cache        LRU cache
 * @return              0 on success, error code on failure
int kr_nsrep_update_rep(struct kr_nsrep *ns, unsigned reputation, kr_nsrep_lru_t *cache);