aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-23 11:23:22 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-23 21:14:12 -0700
commit8ad296769192cf4628710ac0b228be2aca6d8dad (patch)
treeedd6240a63cc3b2a7e6206e1cc07b5c5edb9f1bf /src/core
parent7074c5c50936308d1ef58be4ce1ca5e776e4c8cb (diff)
downloadnng-8ad296769192cf4628710ac0b228be2aca6d8dad.tar.gz
nng-8ad296769192cf4628710ac0b228be2aca6d8dad.tar.bz2
nng-8ad296769192cf4628710ac0b228be2aca6d8dad.zip
Implement dynamic option numbering.
This permits option numbers to be allocated based on string name. Eventually all the option values will be replaced with option names. This will facilitate transports (ZeroTier) that may need further options.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/init.c2
-rw-r--r--src/core/options.c157
-rw-r--r--src/core/options.h7
3 files changed, 166 insertions, 0 deletions
diff --git a/src/core/init.c b/src/core/init.c
index 4025c0f4..54c72c5e 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -21,6 +21,7 @@ nni_init_helper(void)
((rv = nni_timer_sys_init()) != 0) ||
((rv = nni_aio_sys_init()) != 0) ||
((rv = nni_random_sys_init()) != 0) ||
+ ((rv = nni_option_sys_init()) != 0) ||
((rv = nni_sock_sys_init()) != 0) ||
((rv = nni_ep_sys_init()) != 0) ||
((rv = nni_pipe_sys_init()) != 0) ||
@@ -43,6 +44,7 @@ nni_fini(void)
nni_pipe_sys_fini();
nni_ep_sys_fini();
nni_sock_sys_fini();
+ nni_option_sys_fini();
nni_random_sys_fini();
nni_aio_sys_fini();
nni_timer_sys_fini();
diff --git a/src/core/options.c b/src/core/options.c
index ecfa437e..55797218 100644
--- a/src/core/options.c
+++ b/src/core/options.c
@@ -10,8 +10,22 @@
#include "core/nng_impl.h"
+#include <stdio.h>
#include <string.h>
+// Dynamic options.
+
+typedef struct nni_option nni_option;
+struct nni_option {
+ nni_list_node o_link;
+ char * o_name;
+ int o_id;
+};
+
+static nni_mtx nni_option_lk;
+static nni_list nni_options;
+static int nni_option_nextid;
+
int
nni_chkopt_usec(const void *v, size_t sz)
{
@@ -241,3 +255,146 @@ nni_getopt_fd(nni_sock *s, nni_notifyfd *fd, int mask, void *val, size_t *szp)
memcpy(val, &fd->sn_rfd, sizeof(int));
return (0);
}
+
+// nni_option_set_id sets the id for an option, if not already done so.
+// (Some options have hard coded values that end-user may depend upon.)
+// If the ID passed in is negative, then a new ID is allocated dynamically.
+static int
+nni_option_set_id(const char *name, int id)
+{
+ nni_option *opt;
+ int len;
+ nni_mtx_lock(&nni_option_lk);
+ NNI_LIST_FOREACH (&nni_options, opt) {
+ if (strcmp(name, opt->o_name) == 0) {
+ nni_mtx_unlock(&nni_option_lk);
+ return (0);
+ }
+ }
+ if ((opt = NNI_ALLOC_STRUCT(opt)) == NULL) {
+ nni_mtx_unlock(&nni_option_lk);
+ return (NNG_ENOMEM);
+ }
+ len = strlen(name) + 1;
+ if ((opt->o_name = nni_alloc(len)) == NULL) {
+ nni_mtx_unlock(&nni_option_lk);
+ NNI_FREE_STRUCT(opt);
+ return (NNG_ENOMEM);
+ }
+ (void) snprintf(opt->o_name, len, "%s", name);
+ if (id < 0) {
+ id = nni_option_nextid++;
+ }
+ opt->o_id = id;
+ nni_list_append(&nni_options, opt);
+ nni_mtx_unlock(&nni_option_lk);
+ return (0);
+}
+
+int
+nni_option_lookup(const char *name)
+{
+ nni_option *opt;
+ int id = -1;
+
+ nni_mtx_lock(&nni_option_lk);
+ NNI_LIST_FOREACH (&nni_options, opt) {
+ if (strcmp(name, opt->o_name) == 0) {
+ id = opt->o_id;
+ break;
+ }
+ }
+ nni_mtx_unlock(&nni_option_lk);
+ return (id);
+}
+
+const char *
+nni_option_name(int id)
+{
+ nni_option *opt;
+ const char *name = NULL;
+
+ nni_mtx_lock(&nni_option_lk);
+ NNI_LIST_FOREACH (&nni_options, opt) {
+ if (id == opt->o_id) {
+ name = opt->o_name;
+ break;
+ }
+ }
+ nni_mtx_unlock(&nni_option_lk);
+ return (name);
+}
+
+int
+nni_option_register(const char *name, int *idp)
+{
+ int id;
+ int rv;
+
+ // Note that if the id was already in use, we will
+ // wind up leaving a gap in the ID space. That should
+ // be inconsequential.
+ if ((rv = nni_option_set_id(name, -1)) != 0) {
+ return (rv);
+ }
+ *idp = nni_option_lookup(name);
+ return (0);
+}
+
+int
+nni_option_sys_init(void)
+{
+ nni_mtx_init(&nni_option_lk);
+ NNI_LIST_INIT(&nni_options, nni_option, o_link);
+ nni_option_nextid = 0x10000;
+ int rv;
+
+ // Register our well-known options.
+ if (((rv = nni_option_set_id("raw", NNG_OPT_RAW)) != 0) ||
+ ((rv = nni_option_set_id("linger", NNG_OPT_LINGER)) != 0) ||
+ ((rv = nni_option_set_id("recv-buf", NNG_OPT_RCVBUF)) != 0) ||
+ ((rv = nni_option_set_id("send-buf", NNG_OPT_SNDBUF)) != 0) ||
+ ((rv = nni_option_set_id("recv-timeout", NNG_OPT_RCVTIMEO)) !=
+ 0) ||
+ ((rv = nni_option_set_id("send-timeout", NNG_OPT_SNDTIMEO)) !=
+ 0) ||
+ ((rv = nni_option_set_id("reconnect-time", NNG_OPT_RECONN_TIME)) !=
+ 0) ||
+ ((rv = nni_option_set_id(
+ "reconnect-max-time", NNG_OPT_RECONN_MAXTIME)) != 0) ||
+ ((rv = nni_option_set_id("recv-max-size", NNG_OPT_RCVMAXSZ)) !=
+ 0) ||
+ ((rv = nni_option_set_id("max-ttl", NNG_OPT_MAXTTL)) != 0) ||
+ ((rv = nni_option_set_id("protocol", NNG_OPT_PROTOCOL)) != 0) ||
+ ((rv = nni_option_set_id("subscribe", NNG_OPT_SUBSCRIBE)) != 0) ||
+ ((rv = nni_option_set_id("unsubscribe", NNG_OPT_UNSUBSCRIBE)) !=
+ 0) ||
+ ((rv = nni_option_set_id("survey-time", NNG_OPT_SURVEYTIME)) !=
+ 0) ||
+ ((rv = nni_option_set_id("resend-time", NNG_OPT_RESENDTIME)) !=
+ 0) ||
+ ((rv = nni_option_set_id("transport", NNG_OPT_TRANSPORT)) != 0) ||
+ ((rv = nni_option_set_id("local-addr", NNG_OPT_LOCALADDR)) != 0) ||
+ ((rv = nni_option_set_id("remote-addr", NNG_OPT_REMOTEADDR)) !=
+ 0) ||
+ ((rv = nni_option_set_id("recv-fd", NNG_OPT_RCVFD)) != 0) ||
+ ((rv = nni_option_set_id("send-fd", NNG_OPT_SNDFD)) != 0)) {
+ nni_option_sys_fini();
+ return (rv);
+ }
+ return (0);
+}
+
+void
+nni_option_sys_fini(void)
+{
+ if (nni_option_nextid != 0) {
+ nni_option *opt;
+ while ((opt = nni_list_first(&nni_options)) != NULL) {
+ nni_list_remove(&nni_options, opt);
+ nni_free(opt->o_name, strlen(opt->o_name) + 1);
+ NNI_FREE_STRUCT(opt);
+ }
+ }
+ nni_option_nextid = 0;
+} \ No newline at end of file
diff --git a/src/core/options.h b/src/core/options.h
index 4b29c4b6..03a6e37e 100644
--- a/src/core/options.h
+++ b/src/core/options.h
@@ -56,4 +56,11 @@ extern int nni_chkopt_usec(const void *, size_t);
extern int nni_chkopt_int(const void *, size_t, int, int);
extern int nni_chkopt_size(const void *, size_t, size_t, size_t);
+extern int nni_option_register(const char *, int *);
+extern int nni_option_lookup(const char *);
+extern const char *nni_option_name(int);
+
+extern int nni_option_sys_init(void);
+extern void nni_option_sys_fini(void);
+
#endif // CORE_OPTIONS_H