nsrep.h 4.66 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*  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
14
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
15 16 17 18
 */

#pragma once

19
#include <netinet/in.h>
20
#include <sys/socket.h>
Marek Vavruša's avatar
Marek Vavruša committed
21
#include <libknot/dname.h>
22
#include <limits.h>
23

24
#include "lib/defines.h"
25
#include "lib/generic/map.h"
26
#include "lib/generic/lru.h"
27

28 29
struct kr_query;

Marek Vavruša's avatar
Marek Vavruša committed
30
/** 
31 32
  * NS RTT score (special values).
  * @note RTT is measured in milliseconds.
Marek Vavruša's avatar
Marek Vavruša committed
33
  */
34
enum kr_ns_score {
35
	KR_NS_MAX_SCORE = KR_CONN_RTT_MAX,
36
	KR_NS_TIMEOUT   = (95 * KR_NS_MAX_SCORE) / 100,
37
	KR_NS_LONG      = (3 * KR_NS_TIMEOUT) / 4,
38
	KR_NS_UNKNOWN   = KR_NS_TIMEOUT / 2,
39
	KR_NS_PENALTY   = 100,
40
	KR_NS_GLUED     = 10
41 42
};

43 44 45 46 47 48 49 50 51
/**
 * 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 */
};

52 53 54 55
/**
 * NS RTT update modes.
 */
enum kr_ns_update_mode {
56 57
	KR_NS_UPDATE = 0, /**< Update as smooth over last two measurements */
	KR_NS_RESET,      /**< Set to given value */
58 59
	KR_NS_ADD,        /**< Increment current value */
	KR_NS_MAX         /**< Set to maximum of current/proposed value. */
60 61
};

62 63 64
/**
 * NS reputation/QoS tracking.
 */
65
typedef lru_t(unsigned) kr_nsrep_lru_t;
66

67
/* Maximum count of addresses probed in one go (last is left empty) */
68
#define KR_NSREP_MAXADDR 4
69

Marek Vavruša's avatar
Marek Vavruša committed
70 71 72 73 74
/**
 * Name server representation.
 * Contains extra information about the name server, e.g. score
 * or other metadata.
 */
75 76
struct kr_nsrep
{
77 78 79 80
	unsigned score;                  /**< NS score */
	unsigned reputation;             /**< NS reputation */
	const knot_dname_t *name;        /**< NS name */
	struct kr_context *ctx;          /**< Resolution context */
81 82 83 84
	union {
		struct sockaddr ip;
		struct sockaddr_in ip4;
		struct sockaddr_in6 ip6;
85
	} addr[KR_NSREP_MAXADDR];        /**< NS address(es) */
86 87
};

88 89 90 91 92 93 94
/** @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))

95 96 97
/**
 * Set given NS address.
 * @param  qry      updated query
98
 * @param  index    index of the updated target
99 100
 * @param  addr     address bytes (struct in_addr or struct in6_addr)
 * @param  addr_len address bytes length (type will be derived from this)
101
 * @param  port     address port (if <= 0, 53 will be used)
102 103
 * @return          0 or an error code
 */
104
KR_EXPORT
105
int kr_nsrep_set(struct kr_query *qry, size_t index, uint8_t *addr, size_t addr_len, int port);
106

107 108
/**
 * Elect best nameserver/address pair from the nsset.
109 110 111
 * @param  qry          updated query
 * @param  ctx          resolution context
 * @return              0 or an error code
112
 */
113
KR_EXPORT
114
int kr_nsrep_elect(struct kr_query *qry, struct kr_context *ctx);
115

116 117 118 119 120 121
/**
 * Elect best nameserver/address pair from the nsset.
 * @param  qry          updated query
 * @param  ctx          resolution context
 * @return              0 or an error code
 */
122
KR_EXPORT
123 124
int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx);

125
/**
126
 * Update NS address RTT information.
127
 *
128
 * @brief In KR_NS_UPDATE mode reputation is smoothed over last N measurements.
129 130
 * 
 * @param  ns           updated NS representation
131
 * @param  addr         chosen address (NULL for first)
132
 * @param  score        new score (i.e. RTT), see enum kr_ns_score
133
 * @param  cache        LRU cache
134
 * @param  umode        update mode (KR_NS_UPDATE or KR_NS_RESET or KR_NS_ADD)
135 136
 * @return              0 on success, error code on failure
 */
137
KR_EXPORT
138 139
int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
			unsigned score, kr_nsrep_lru_t *cache, int umode);
140 141

/**
142
 * Update NSSET reputation information.
143 144 145 146
 * 
 * @param  ns           updated NS representation
 * @param  reputation   combined reputation flags, see enum kr_ns_rep
 * @param  cache        LRU cache
147
 * @return              0 on success, error code on failure
148
 */
149
KR_EXPORT
150
int kr_nsrep_update_rep(struct kr_nsrep *ns, unsigned reputation, kr_nsrep_lru_t *cache);