Skip to content
Snippets Groups Projects
Commit 4080d6d5 authored by Vladimír Čunát's avatar Vladimír Čunát
Browse files

hints: allow removing hints

Fixes #111.

Compatibility: it needs a new libkres.so function.  If a wrong version
combination is attempted, the module just cleanly fails to load, though
it writes a slightly confusing message "no such file or directory".
parent 82ccbbd3
Branches
Tags
1 merge request!82hints: allow removing hints
...@@ -267,6 +267,21 @@ int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd ...@@ -267,6 +267,21 @@ int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd
return ret; return ret;
} }
int kr_zonecut_del_all(struct kr_zonecut *cut, const knot_dname_t *ns)
{
if (!cut || !ns) {
return kr_error(EINVAL);
}
/* Find the address list; then free and remove it. */
pack_t *pack = kr_zonecut_find(cut, ns);
if (pack == NULL) {
return kr_error(ENOENT);
}
free_addr_set((const char *)ns, pack, cut->pool);
return map_del(&cut->nsset, (const char *)ns);
}
pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns) pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns)
{ {
if (!cut || !ns) { if (!cut || !ns) {
......
...@@ -104,6 +104,15 @@ int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd ...@@ -104,6 +104,15 @@ int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd
KR_EXPORT KR_EXPORT
int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rdata_t *rdata); int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rdata_t *rdata);
/**
* Delete all addresses associated with the given name.
* @param cut
* @param ns name server name
* @return 0 or error code
*/
KR_EXPORT
int kr_zonecut_del_all(struct kr_zonecut *cut, const knot_dname_t *ns);
/** /**
* Find nameserver address list in the zone cut. * Find nameserver address list in the zone cut.
* *
......
...@@ -30,7 +30,7 @@ Properties ...@@ -30,7 +30,7 @@ Properties
:param string path: path to hosts file, default: ``"/etc/hosts"`` :param string path: path to hosts file, default: ``"/etc/hosts"``
:return: ``{ result: bool }`` :return: ``{ result: bool }``
Load specified hosts file. Load specified hosts file.
.. function:: hints.get(hostname) .. function:: hints.get(hostname)
...@@ -45,7 +45,14 @@ Properties ...@@ -45,7 +45,14 @@ Properties
:param string pair: ``hostname address`` i.e. ``"localhost 127.0.0.1"`` :param string pair: ``hostname address`` i.e. ``"localhost 127.0.0.1"``
:return: ``{ result: bool }`` :return: ``{ result: bool }``
Set hostname - address pair hint. Add a hostname - address pair hint.
.. function:: hints.del(pair)
:param string pair: ``hostname address`` i.e. ``"localhost 127.0.0.1"``, or just ``hostname``
:return: ``{ result: bool }``
Remove a hostname - address pair hint. If address is omitted, all addresses for the given name are deleted.
.. function:: hints.root() .. function:: hints.root()
...@@ -76,4 +83,4 @@ Properties ...@@ -76,4 +83,4 @@ Properties
} }
.. tip:: A good rule of thumb is to select only a few fastest root hints. The server learns RTT and NS quality over time, and thus tries all servers available. You can help it by preselecting the candidates. .. tip:: A good rule of thumb is to select only a few fastest root hints. The server learns RTT and NS quality over time, and thus tries all servers available. You can help it by preselecting the candidates.
\ No newline at end of file
...@@ -216,6 +216,22 @@ static int parse_addr_str(struct sockaddr_storage *sa, const char *addr) ...@@ -216,6 +216,22 @@ static int parse_addr_str(struct sockaddr_storage *sa, const char *addr)
return 0; return 0;
} }
/** @warning _NOT_ thread-safe; returns a pointer to static data! */
static const knot_rdata_t * addr2rdata(const char *addr) {
/* Parse address string */
struct sockaddr_storage ss;
if (parse_addr_str(&ss, addr) != 0) {
return NULL;
}
/* Build RDATA */
static knot_rdata_t rdata_arr[RDATA_ARR_MAX];
size_t addr_len = kr_inaddr_len((struct sockaddr *)&ss);
const uint8_t *raw_addr = (const uint8_t *)kr_inaddr((struct sockaddr *)&ss);
knot_rdata_init(rdata_arr, addr_len, raw_addr, 0);
return rdata_arr;
}
static int add_pair(struct kr_zonecut *hints, const char *name, const char *addr) static int add_pair(struct kr_zonecut *hints, const char *name, const char *addr)
{ {
/* Build key */ /* Build key */
...@@ -223,20 +239,34 @@ static int add_pair(struct kr_zonecut *hints, const char *name, const char *addr ...@@ -223,20 +239,34 @@ static int add_pair(struct kr_zonecut *hints, const char *name, const char *addr
if (!knot_dname_from_str(key, name, sizeof(key))) { if (!knot_dname_from_str(key, name, sizeof(key))) {
return kr_error(EINVAL); return kr_error(EINVAL);
} }
const knot_rdata_t *rdata = addr2rdata(addr);
if (!rdata) {
return kr_error(EINVAL);
}
/* Parse address string */ return kr_zonecut_add(hints, key, rdata);
struct sockaddr_storage ss; }
if (parse_addr_str(&ss, addr) != 0) {
/** For a given name, remove either one address or all of them (if == NULL). */
static int del_pair(struct kr_zonecut *hints, const char *name, const char *addr)
{
/* Build key */
knot_dname_t key[KNOT_DNAME_MAXLEN];
if (!knot_dname_from_str(key, name, sizeof(key))) {
return kr_error(EINVAL); return kr_error(EINVAL);
} }
/* Build RDATA */ if (addr) {
size_t addr_len = kr_inaddr_len((struct sockaddr *)&ss); /* Remove the pair. */
const uint8_t *raw_addr = (const uint8_t *)kr_inaddr((struct sockaddr *)&ss); const knot_rdata_t *rdata = addr2rdata(addr);
/* @warning _NOT_ thread-safe */ if (!rdata) {
static knot_rdata_t rdata_arr[RDATA_ARR_MAX]; return kr_error(EINVAL);
knot_rdata_init(rdata_arr, addr_len, raw_addr, 0); }
return kr_zonecut_add(hints, key, rdata_arr); return kr_zonecut_del(hints, key, rdata);
} else {
/* Remove the whole name. */
return kr_zonecut_del_all(hints, key);
}
} }
static int load_map(struct kr_zonecut *hints, FILE *fp) static int load_map(struct kr_zonecut *hints, FILE *fp)
...@@ -327,6 +357,25 @@ static char* hint_set(void *env, struct kr_module *module, const char *args) ...@@ -327,6 +357,25 @@ static char* hint_set(void *env, struct kr_module *module, const char *args)
return result; return result;
} }
static char* hint_del(void *env, struct kr_module *module, const char *args)
{
struct kr_zonecut *hints = module->data;
auto_free char *args_copy = strdup(args);
int ret = -1;
char *addr = strchr(args_copy, ' ');
if (addr) {
*addr = '\0';
++addr;
}
ret = del_pair(hints, args_copy, addr);
char *result = NULL;
if (-1 == asprintf(&result, "{ \"result\": %s }", ret == 0 ? "true" : "false"))
result = NULL;
return result;
}
/** @internal Pack address list into JSON array. */ /** @internal Pack address list into JSON array. */
static JsonNode *pack_addrs(pack_t *pack) static JsonNode *pack_addrs(pack_t *pack)
{ {
...@@ -471,6 +520,7 @@ struct kr_prop *hints_props(void) ...@@ -471,6 +520,7 @@ struct kr_prop *hints_props(void)
{ {
static struct kr_prop prop_list[] = { static struct kr_prop prop_list[] = {
{ &hint_set, "set", "Set {name, address} hint.", }, { &hint_set, "set", "Set {name, address} hint.", },
{ &hint_del, "del", "Delete one {name, address} hint or all addresses for the name.", },
{ &hint_get, "get", "Retrieve hint for given name.", }, { &hint_get, "get", "Retrieve hint for given name.", },
{ &hint_root, "root", "Replace root hints set (empty value to return current list).", }, { &hint_root, "root", "Replace root hints set (empty value to return current list).", },
{ NULL, NULL, NULL } { NULL, NULL, NULL }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment