]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
get and set option more accessible.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 23 Feb 2010 13:53:10 +0000 (13:53 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 23 Feb 2010 13:53:10 +0000 (13:53 +0000)
git-svn-id: file:///svn/unbound/trunk@1990 be551aaa-1e26-0410-a405-d3ace91eadb9

16 files changed:
daemon/remote.c
daemon/remote.h
doc/Changelog
doc/libunbound.3.in
doc/unbound-control.8.in
libunbound/libunbound.c
libunbound/libworker.c
libunbound/ubsyms.def
libunbound/unbound.h
smallapp/unbound-control.c
smallapp/worker_cb.c
testcode/testbound.c
util/config_file.c
util/config_file.h
util/fptr_wlist.c
util/iana_ports.inc

index 03767d49df13460a54236dda45bde58c9c29c787..2869680630753ffc1f0a1a275462414a42531c3a 100644 (file)
@@ -1469,6 +1469,39 @@ do_log_reopen(SSL* ssl, struct worker* worker)
        log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
 }
 
+/** do the set_option command */
+static void
+do_set_option(SSL* ssl, struct worker* worker, char* arg)
+{
+       char* arg2;
+       if(!find_arg2(ssl, arg, &arg2))
+               return;
+       if(!config_set_option(worker->env.cfg, arg, arg2)) {
+               (void)ssl_printf(ssl, "error setting option\n");
+               return;
+       }
+       send_ok(ssl);
+}
+
+/* routine to printout option values over SSL */
+void remote_get_opt_ssl(char* line, void* arg)
+{
+       SSL* ssl = (SSL*)arg;
+       (void)ssl_printf(ssl, "%s\n", line);
+}
+
+/** do the get_option command */
+static void
+do_get_option(SSL* ssl, struct worker* worker, char* arg)
+{
+       int r;
+       r = config_get_option(worker->env.cfg, arg, remote_get_opt_ssl, ssl);
+       if(!r) {
+               (void)ssl_printf(ssl, "error unknown option\n");
+               return;
+       }
+}
+
 /** tell other processes to execute the command */
 void
 distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
@@ -1564,6 +1597,10 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
                do_dump_requestlist(ssl, worker);
        } else if(strncmp(p, "log_reopen", 10) == 0) {
                do_log_reopen(ssl, worker);
+       } else if(strncmp(p, "set_option", 10) == 0) {
+               do_set_option(ssl, worker, skipwhite(p+10));
+       } else if(strncmp(p, "get_option", 10) == 0) {
+               do_get_option(ssl, worker, skipwhite(p+10));
        } else {
                (void)ssl_printf(ssl, "error unknown command '%s'\n", p);
        }
index cdbab9ba8c689f295ebe70d3f8ae0e70ed376e3c..bd58cbc90b7c62c8d2474a5ed9b919b6c0aff32a 100644 (file)
@@ -171,4 +171,7 @@ int ssl_printf(SSL* ssl, const char* format, ...)
  */
 int ssl_read_line(SSL* ssl, char* buf, size_t max);
 
+/** routine to printout option values over SSL */
+void remote_get_opt_ssl(char* line, void* arg);
+
 #endif /* DAEMON_REMOTE_H */
index b4b1ae7e68e6b1a8ab26974ae14e8b39c680a689..3060b97df9c643cde384bbfade87ad35116f6264 100644 (file)
@@ -1,3 +1,8 @@
+23 February 2010: Wouter
+       - libunbound ub_ctx_get_option() added.
+       - unbound-control set_option and get_option commands.
+       - iana portlist updated.
+
 18 February 2010: Wouter
        - A little more strict DS scrubbing.
        - No more blacklisting of unresponsive servers, a 2 minute timeout
index 1adfb73171bc914bf19a65b3d1c0200126d09092..80041fd44f9b9dc87cc82214df0cbbee75f7eeee 100644 (file)
@@ -17,6 +17,7 @@
 .B ub_ctx_create,
 .B ub_ctx_delete,
 .B ub_ctx_set_option,
+.B ub_ctx_get_option,
 .B ub_ctx_config,
 .B ub_ctx_set_fwd,
 .B ub_ctx_resolvconf,
@@ -56,6 +57,9 @@
 \fBub_ctx_set_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar*\fR val);
 .LP
 \fIint\fR
+\fBub_ctx_get_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar**\fR val);
+.LP
+\fIint\fR
 \fBub_ctx_config\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
 .LP
 \fIint\fR
@@ -178,6 +182,11 @@ config file format, see \fIunbound.conf\fR(5). Not all options are
 relevant. For some specific options, such as adding trust anchors, special
 routines exist. Pass the option name with the trailing ':'.
 .TP
+.B ub_ctx_get_option
+A power\-user interface that gets an option value.  Some options cannot be
+gotten, and others return a newline separated list.  Pass the option name
+without trailing ':'.  The returned value must be free(2)d by the caller.
+.TP
 .B ub_ctx_config
 A power\-user interface that lets you specify an unbound config file, see
 \fIunbound.conf\fR(5), which is read for configuration. Not all options are
index 06434140a04e5272a2a587d0d4dc24eee3355a55..ee66943116d1f07c5e2b2d3053f56aadc59891eb 100644 (file)
@@ -142,7 +142,20 @@ Show what is worked on.  Prints all queries that the server is currently
 working on.  Prints the time that users have been waiting.  For internal
 requests, no time is printed.  And then prints out the module status.
 .TP
-.B forward [off | addr ... ]
+.B set_option \fIopt: val
+Set the option to the given value without a reload.  The cache is therefore
+not flushed.  The option must end with a ':' and whitespace must be between the
+option and the value.  Some values may not have an effect if set this way,
+not all options are supported.
+.TP
+.B get_option \fIopt
+Get the value of the option.  Give the option name without a trailing ':'.
+The value is printed.  If the value is "", nothing is printed and the
+connection closes.  On error 'error ...' is printed (it gives a syntax
+error on unknown option).  For some options a list of values, one on
+each line, is printed.  Not all options are supported.
+.TP
+.B forward \fR[\fIoff\fR | \fIaddr ...\fR ]
 Setup forwarding mode.  Configures if the server should ask other upstream
 nameservers, should go to the internet root nameservers itself, or show 
 the current config.  You could pass the nameservers after a DHCP update.
index a30177d725570cd5a8563937aa8beacd6f617c2b..aae452ace37a21f5046a40b81e7303f3bfd869da 100644 (file)
@@ -243,6 +243,19 @@ ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val)
        return UB_NOERROR;
 }
 
+int
+ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** str)
+{
+       int r;
+       lock_basic_lock(&ctx->cfglock);
+       r = config_get_option_collate(ctx->env->cfg, opt, str);
+       lock_basic_unlock(&ctx->cfglock);
+       if(r == 0) r = UB_NOERROR;
+       else if(r == 1) r = UB_SYNTAX;
+       else if(r == 2) r = UB_NOMEM;
+       return r;
+}
+
 int 
 ub_ctx_config(struct ub_ctx* ctx, char* fname)
 {
index f23b1af67a5c396c2a352cc7f7da306eb311d26d..315a791b310df54557d573f7a8ad77556320c476 100644 (file)
@@ -868,6 +868,11 @@ int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
         return 0;
 }
 
+void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
+{
+        log_assert(0);
+}
+
 #ifdef UB_ON_WINDOWS
 void
 worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* 
index 0d50a2b9e3620160edee5b2088decfcb3900e96c..74d671f1e56a550c95c46b2f8bfb36c606338699 100644 (file)
@@ -1,5 +1,6 @@
 ub_ctx_create
 ub_ctx_delete
+ub_ctx_get_option
 ub_ctx_set_option
 ub_ctx_config
 ub_ctx_set_fwd
index bbbe6038799e41c2498d114a735fa52a4058deeb..174c5bc6bd5c29a2cdd381605345a066b6588f01 100644 (file)
@@ -227,7 +227,7 @@ void ub_ctx_delete(struct ub_ctx* ctx);
  * @param ctx: context.
  * @param opt: option name from the unbound.conf config file format.
  *     (not all settings applicable). The name includes the trailing ':'
- *     for example ub_ctx_set_option("logfile:", "mylog.txt");
+ *     for example ub_ctx_set_option(ctx, "logfile:", "mylog.txt");
  *     This is a power-users interface that lets you specify all sorts
  *     of options.
  *     For some specific options, such as adding trust anchors, special
@@ -237,6 +237,22 @@ void ub_ctx_delete(struct ub_ctx* ctx);
  */
 int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val);
 
+/**
+ * Get an option from the context.
+ * @param ctx: context.
+ * @param opt: option name from the unbound.conf config file format.
+ *     (not all settings applicable). The name excludes the trailing ':'
+ *     for example ub_ctx_get_option(ctx, "logfile", &result);
+ *     This is a power-users interface that lets you specify all sorts
+ *     of options.
+ * @param str: the string is malloced and returned here. NULL on error.
+ *     The caller must free() the string.  In cases with multiple 
+ *     entries (auto-trust-anchor-file), a newline delimited list is 
+ *     returned in the string.
+ * @return 0 if OK else an error code (malloc failure, syntax error).
+ */
+int ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** str);
+
 /**
  * setup configuration for the given context.
  * @param ctx: context.
index b60fb231ff20027e0de66a098f5b90ed8a21a89a..5794857423a7fa054ee4e886c983ee8e9337cf03 100644 (file)
@@ -84,6 +84,8 @@ usage()
        printf("  flush_stats                   flush statistics, make zero\n");
        printf("  flush_requestlist             drop queries that are worked on\n");
        printf("  dump_requestlist              show what is worked on\n");
+       printf("  set_option opt: val           set option to value, no reload\n");
+       printf("  get_option opt                get option value\n");
        printf("  forward [off | addr ...]      without arg show forward setup\n");
        printf("                                or off to turn off root forwarding\n");
        printf("                                or give list of ip addresses\n");
index 02774c7566944d7fc6ff4d49019e9b4349433afc..78ee0196349ccad3bec5ced2aa5337715b5e5099 100644 (file)
@@ -241,3 +241,8 @@ int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
         log_assert(0);
         return 0;
 }
+
+void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
+{
+        log_assert(0);
+}
index c461b641c97bb7ff6d2da2a85fbbef621d645498..f61eea9bdfc3a160e603a06c0403287ab466a9dd 100644 (file)
@@ -389,6 +389,11 @@ int remote_control_callback(struct comm_point* ATTR_UNUSED(c),
        return 0;
 }
 
+void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
+{
+        log_assert(0);
+}
+
 void wsvc_command_option(const char* ATTR_UNUSED(wopt), 
        const char* ATTR_UNUSED(cfgfile), int ATTR_UNUSED(v), 
        int ATTR_UNUSED(c))
index e3a3bf92f264f6bd15e2a22d343959e0441ed201..d34a3142f16f6331834c164b0f67e4c54e2c8625 100644 (file)
@@ -512,13 +512,91 @@ void config_print_func(char* line, void* arg)
        (void)fprintf(f, "%s\n", line);
 }
 
+/** collate func arg */
+struct config_collate_arg {
+       /** list of result items */
+       struct config_strlist_head list;
+       /** if a malloc error occurred, 0 is OK */
+       int status;
+};
+
+void config_collate_func(char* line, void* arg)
+{
+       struct config_collate_arg* m = (struct config_collate_arg*)arg;
+       if(m->status)
+               return;
+       if(!cfg_strlist_append(&m->list, strdup(line)))
+               m->status = 1;
+}
+
+int config_get_option_list(struct config_file* cfg, const char* opt,
+        struct config_strlist** list)
+{
+       struct config_collate_arg m;
+       memset(&m, 0, sizeof(m));
+       *list = NULL;
+       if(!config_get_option(cfg, opt, config_collate_func, &m))
+               return 1;
+       if(m.status) {
+               config_delstrlist(m.list.first);
+               return 2;
+       }
+       *list = m.list.first;
+       return 0;
+}
+
+int
+config_get_option_collate(struct config_file* cfg, const char* opt, char** str)
+{
+       struct config_strlist* list = NULL;
+       int r;
+       *str = NULL;
+       if((r = config_get_option_list(cfg, opt, &list)) != 0)
+               return r;
+       *str = config_collate_cat(list);
+       config_delstrlist(list);
+       if(!*str) return 2;
+       return 0;
+}
+
+char*
+config_collate_cat(struct config_strlist* list)
+{
+       size_t total = 0, left;
+       struct config_strlist* s;
+       char *r, *w;
+       if(!list) /* no elements */
+               return strdup("");
+       if(list->next == NULL) /* one element , no newline at end. */
+               return strdup(list->str);
+       /* count total length */
+       for(s=list; s; s=s->next)
+               total += strlen(s->str) + 1; /* len + newline */
+       left = total+1; /* one extra for nul at end */
+       r = malloc(left); 
+       if(!r)
+               return NULL;
+       w = r;
+       for(s=list; s; s=s->next) {
+               size_t this = strlen(s->str);
+               if(this+2 > left) { /* sanity check */
+                       free(r);
+                       return NULL;
+               }
+               snprintf(w, left, "%s\n", s->str);
+               w += this+1;
+               left -= this+1;
+       }
+       return r;
+}
+
 int
 config_get_option(struct config_file* cfg, const char* opt, 
        void (*func)(char*,void*), void* arg)
 {
        char buf[1024];
        size_t len = sizeof(buf);
-       fptr_whitelist_print_func(func);
+       fptr_ok(fptr_whitelist_print_func(func));
        O_DEC(opt, "verbosity", verbosity)
        else O_DEC(opt, "statistics-interval", stat_interval)
        else O_YNO(opt, "statistics-cumulative", stat_interval)
@@ -869,6 +947,24 @@ int ub_c_wrap()
        return 1;
 }
 
+int cfg_strlist_append(struct config_strlist_head* list, char* item)
+{
+       struct config_strlist *s;
+       if(!item || !list)
+               return 0;
+       s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist));
+       if(!s)
+               return 0;
+       s->str = item;
+       s->next = NULL;
+       if(list->last)
+               list->last->next = s;
+       else
+               list->first = s;
+       list->last = s;
+       return 1;
+}
+
 int 
 cfg_strlist_insert(struct config_strlist** head, char* item)
 {
index fb136346ec8a67f42c3b2a2520006f90788c6faf..0ad374f449b93a988f98ebf7d3537eebfcca13ad 100644 (file)
@@ -315,6 +315,14 @@ struct config_str2list {
        char* str2;
 };
 
+/** List head for strlist processing, used for append operation. */
+struct config_strlist_head {
+       /** first in list of text items */
+       struct config_strlist* first;
+       /** last in list of text items */
+       struct config_strlist* last;
+};
+
 /**
  * Create config file structure. Filled with default values.
  * @return: the new structure or NULL on memory error.
@@ -373,6 +381,26 @@ int config_set_option(struct config_file* config, const char* option,
 int config_get_option(struct config_file* cfg, const char* opt, 
        void (*func)(char*,void*), void* arg);
 
+/**
+ * Get an option and return strlist
+ * @param cfg: config file
+ * @param opt: option name.
+ * @param list: list is returned here. malloced, caller must free it.
+ * @return 0=OK, 1=syntax error, 2=malloc failed.
+ */
+int config_get_option_list(struct config_file* cfg, const char* opt,
+       struct config_strlist** list);
+
+/**
+ * Get an option and collate results into string
+ * @param cfg: config file
+ * @param opt: option name.
+ * @param str: string. malloced, caller must free it.
+ * @return 0=OK, 1=syntax error, 2=malloc failed.
+ */
+int config_get_option_collate(struct config_file* cfg, const char* opt, 
+       char** str);
+
 /**
  * function to print to a file, use as func with config_get_option.
  * @param line: text to print. \n appended.
@@ -380,6 +408,28 @@ int config_get_option(struct config_file* cfg, const char* opt,
  */
 void config_print_func(char* line, void* arg);
 
+/**
+ * function to collate the text strings into a strlist_head.
+ * @param line: text to append.
+ * @param arg: pass a strlist_head structure. zeroed on start.
+ */
+void config_collate_func(char* line, void* arg);
+
+/**
+ * take a strlist_head list and return a malloc string. separated with newline.
+ * @param list: strlist first to collate. zeroes return "".
+ * @return NULL on malloc failure. Or if malloc failure happened in strlist.
+ */
+char* config_collate_cat(struct config_strlist* list);
+
+/**
+ * Append text at end of list.
+ * @param list: list head. zeroed at start.
+ * @param item: new item. malloced by caller. if NULL the insertion fails.
+ * @return true on success.
+ */
+int cfg_strlist_append(struct config_strlist_head* list, char* item);
+
 /**
  * Insert string into strlist.
  * @param head: pointer to strlist head variable.
index f77e98674eb67af3d23e91ede75e2087c2ea2a1f..5d96382d81185b1c951b232c60482d958dcdca5d 100644 (file)
@@ -393,5 +393,7 @@ int fptr_whitelist_mesh_cb(mesh_cb_func_t fptr)
 int fptr_whitelist_print_func(void (*fptr)(char*,void*))
 {
        if(fptr == &config_print_func) return 1;
+       else if(fptr == &config_collate_func) return 1;
+       else if(fptr == &remote_get_opt_ssl) return 1;
        return 0;
 }
index d770618ed8ecc296fd9dc8e3b15b44b7384aa2c7..d2820126da10f93d388bb66b68ba823955233dbf 100644 (file)
 4894,
 4899,
 4900,
+4912,
 4914,
 4937,
 4940,
 7164,
 7165,
 7166,
+7169,
 7170,
+7171,
 7174,
 7200,
 7201,