int kr_nsrep_set(struct kr_query *qry, uint8_t *addr, size_t addr_len) { if (!qry || !addr) { return kr_error(EINVAL); } qry->ns.name = (const uint8_t *)""; qry->ns.score = KR_NS_UNKNOWN; qry->ns.reputation = 0; update_nsrep(&qry->ns, 0, addr, addr_len); update_nsrep(&qry->ns, 1, NULL, 0); return kr_ok(); }
int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx) { if (!qry || !ctx) { return kr_error(EINVAL); } /* Get address list for this NS */ struct kr_nsrep *ns = &qry->ns; ELECT_INIT(ns, ctx); pack_t *addr_set = map_get(&qry->zone_cut.nsset, (const char *)ns->name); if (!addr_set) { return kr_error(ENOENT); } /* Evaluate addr list */ uint8_t *addr = NULL; unsigned score = eval_addr_set(addr_set, ctx->cache_rtt, ns->score, &addr); update_nsrep(ns, ns->name, addr, score); return kr_ok(); }
static void update_nsrep_set(struct kr_nsrep *ns, const knot_dname_t *name, uint8_t *addr[], unsigned score) { /* NSLIST is not empty, empty NS cannot be a leader. */ if (!addr[0] && ns->addr[0].ip.sa_family != AF_UNSPEC) { return; } /* Set new NS leader */ ns->name = name; ns->score = score; for (size_t i = 0; i < KR_NSREP_MAXADDR; ++i) { if (addr[i]) { void *addr_val = pack_obj_val(addr[i]); size_t len = pack_obj_len(addr[i]); update_nsrep(ns, i, addr_val, len); } else { break; } } }