UNBOUND_VERSION_MICRO=8
-LIBUNBOUND_CURRENT=5
-LIBUNBOUND_REVISION=11
-LIBUNBOUND_AGE=3
+LIBUNBOUND_CURRENT=6
+LIBUNBOUND_REVISION=0
+LIBUNBOUND_AGE=4
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.0.2 had 0:14:0
# 1.5.5 had 5:8:3
# 1.5.6 had 5:9:3
# 1.5.7 had 5:10:3
-# 1.5.8 had 5:11:3
+# 1.5.8 had 6:0:4 # adds ub_ctx_set_stub
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
-LIBUNBOUND_CURRENT=5
-LIBUNBOUND_REVISION=11
-LIBUNBOUND_AGE=3
+LIBUNBOUND_CURRENT=6
+LIBUNBOUND_REVISION=0
+LIBUNBOUND_AGE=4
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.0.2 had 0:14:0
# 1.5.5 had 5:8:3
# 1.5.6 had 5:9:3
# 1.5.7 had 5:10:3
-# 1.5.8 had 5:11:3
+# 1.5.8 had 6:0:4 # adds ub_ctx_set_stub
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
+23 February 2016: Wouter
+ - ub_ctx_set_stub() function for libunbound to config stub zones.
+
19 February 2016: Wouter
- Print understandable debug log when unusable DS record is seen.
- load gost algorithm if digest is seen before key algorithm.
return UB_NOERROR;
}
+int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
+ int isprime)
+{
+ struct sockaddr_storage storage;
+ socklen_t stlen;
+ uint8_t* nm;
+ int nmlabs;
+ size_t nmlen;
+ char* a;
+ struct config_stub **prev, *elem;
+
+ /* check syntax for zone name */
+ if(!parse_dname(zone, &nm, &nmlen, &nmlabs)) {
+ errno=EINVAL;
+ return UB_SYNTAX; /* should have zone name, or "." for root */
+ }
+ free(nm);
+ nm = NULL;
+
+ /* check syntax for addr (if not NULL) */
+ if(addr!=NULL && !extstrtoaddr(addr, &storage, &stlen)) {
+ errno=EINVAL;
+ return UB_SYNTAX;
+ }
+
+ lock_basic_lock(&ctx->cfglock);
+ if(ctx->finalized) {
+ lock_basic_unlock(&ctx->cfglock);
+ errno=EINVAL;
+ return UB_AFTERFINAL;
+ }
+
+ /* arguments all right, now find or add the stub */
+ prev = &ctx->env->cfg->stubs;
+ elem = cfg_stub_find(&prev, zone);
+ if(!elem && !addr) {
+ /* not found and we want to delete, nothing to do */
+ lock_basic_unlock(&ctx->cfglock);
+ return UB_NOERROR;
+ } else if(elem && !addr) {
+ /* found, and we want to delete */
+ *prev = elem->next;
+ config_delstub(elem);
+ lock_basic_unlock(&ctx->cfglock);
+ return UB_NOERROR;
+ } else if(!elem) {
+ /* not found, create the stub entry */
+ elem=(struct config_stub*)calloc(1, sizeof(struct config_stub));
+ if(elem) elem->name = strdup(zone);
+ if(!elem || !elem->name) {
+ free(elem);
+ lock_basic_unlock(&ctx->cfglock);
+ errno = ENOMEM;
+ return UB_NOMEM;
+ }
+ elem->next = ctx->env->cfg->stubs;
+ ctx->env->cfg->stubs = elem;
+ }
+
+ /* add the address to the list and set settings */
+ elem->isprime = isprime;
+ a = strdup(addr);
+ if(!a) {
+ lock_basic_unlock(&ctx->cfglock);
+ errno = ENOMEM;
+ return UB_NOMEM;
+ }
+ if(!cfg_strlist_insert(&elem->addrs, a)) {
+ lock_basic_unlock(&ctx->cfglock);
+ free(a);
+ errno = ENOMEM;
+ return UB_NOMEM;
+ }
+ lock_basic_unlock(&ctx->cfglock);
+ return UB_NOERROR;
+}
+
int
ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname)
{
*/
int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr);
+/**
+ * Add a stub zone, with given address to send to. This is for custom
+ * root hints or pointing to a local authoritative dns server.
+ * For dns resolvers and the 'DHCP DNS' ip address, use ub_ctx_set_fwd.
+ * This is similar to a stub-zone entry in unbound.conf.
+ *
+ * @param ctx: context.
+ * It is only possible to set configuration before the
+ * first resolve is done.
+ * @param zone: name of the zone, string.
+ * @param addr: address, IP4 or IP6 in string format.
+ * The addr is added to the list of stub-addresses if the entry exists.
+ * If the addr is NULL the stub entry is removed.
+ * @param isprime: set to true to set stub-prime to yes for the stub.
+ * For local authoritative servers, people usually set it to false,
+ * For root hints it should be set to true.
+ * @return 0 if OK, else error.
+ */
+int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
+ int isprime);
+
/**
* Read list of nameservers to use from the filename given.
* Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
return 1;
}
+struct config_stub* cfg_stub_find(struct config_stub*** pp, const char* nm)
+{
+ struct config_stub* p = *(*pp);
+ while(p) {
+ if(strcmp(p->name, nm) == 0)
+ return p;
+ (*pp) = &p->next;
+ p = p->next;
+ }
+ return NULL;
+}
+
void
config_delstrlist(struct config_strlist* p)
{
}
}
+void
+config_delstub(struct config_stub* p)
+{
+ if(!p) return;
+ free(p->name);
+ config_delstrlist(p->hosts);
+ config_delstrlist(p->addrs);
+ free(p);
+}
+
void
config_delstubs(struct config_stub* p)
{
struct config_stub* np;
while(p) {
np = p->next;
- free(p->name);
- config_delstrlist(p->hosts);
- config_delstrlist(p->addrs);
- free(p);
+ config_delstub(p);
p = np;
}
}
*/
int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2);
+/**
+ * Find stub in config list, also returns prevptr (for deletion).
+ * @param pp: call routine with pointer to a pointer to the start of the list,
+ * if the stub is found, on exit, the value contains a pointer to the
+ * next pointer that points to the found element (or to the list start
+ * pointer if it is the first element).
+ * @param nm: name of stub to find.
+ * @return: pointer to config_stub if found, or NULL if not found.
+ */
+struct config_stub* cfg_stub_find(struct config_stub*** pp, const char* nm);
+
/**
* Delete items in config string list.
* @param list: list.
*/
void config_deldblstrlist(struct config_str2list* list);
+/**
+ * Delete a stub item
+ * @param p: stub item
+ */
+void config_delstub(struct config_stub* p);
+
/**
* Delete items in config stub list.
* @param list: list.