aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-17 11:49:16 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-17 11:49:16 -0700
commit76c1fc80c931b086493835d037245ebbb5f8d406 (patch)
treee33b7765f755f7497eff26a9458c09ebe1da94ff /src/core
parenta9633313ec8e578c805cd53b37ba3360d83157bc (diff)
downloadnng-76c1fc80c931b086493835d037245ebbb5f8d406.tar.gz
nng-76c1fc80c931b086493835d037245ebbb5f8d406.tar.bz2
nng-76c1fc80c931b086493835d037245ebbb5f8d406.zip
fixes #39 Transport ops vector should be versioned
This also includes tests for some of the edge cases surrounding pluggable transports, such as version mismatch, duplication registration, and failure to initialize.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/transport.c15
-rw-r--r--src/core/transport.h19
2 files changed, 33 insertions, 1 deletions
diff --git a/src/core/transport.c b/src/core/transport.c
index 6f73a6b2..2f373f9a 100644
--- a/src/core/transport.c
+++ b/src/core/transport.c
@@ -27,6 +27,7 @@ typedef struct nni_transport {
static nni_list nni_tran_list;
static nni_mtx nni_tran_lk;
+static int nni_tran_inited;
int
nni_tran_register(const nni_tran *tran)
@@ -34,6 +35,18 @@ nni_tran_register(const nni_tran *tran)
nni_transport *t;
int rv;
+ // Its entirely possible that we are called before any sockets
+ // are opened. Make sure we are initialized. This has to be
+ // protected by a guard to prevent infinite recursion, since
+ // nni_init also winds up calling us.
+ if (!nni_tran_inited) {
+ nni_init();
+ }
+
+ if (tran->tran_version != NNI_TRANSPORT_VERSION) {
+ return (NNG_ENOTSUP);
+ }
+
nni_mtx_lock(&nni_tran_lk);
// Check to see if the transport is already registered...
NNI_LIST_FOREACH (&nni_tran_list, t) {
@@ -83,6 +96,7 @@ nni_tran_sys_init(void)
{
int rv;
+ nni_tran_inited = 1;
NNI_LIST_INIT(&nni_tran_list, nni_transport, t_node);
nni_mtx_init(&nni_tran_lk);
@@ -108,4 +122,5 @@ nni_tran_sys_fini(void)
NNI_FREE_STRUCT(t);
}
nni_mtx_fini(&nni_tran_lk);
+ nni_tran_inited = 0;
}
diff --git a/src/core/transport.h b/src/core/transport.h
index 11cdcf99..78cb2bbf 100644
--- a/src/core/transport.h
+++ b/src/core/transport.h
@@ -1,5 +1,6 @@
//
-// Copyright 2016 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -14,6 +15,11 @@
// interfaces in this file.
struct nni_tran {
+ // tran_version is the version of the transport ops that this
+ // transport implements. We only bother to version the main
+ // ops vector.
+ uint32_t tran_version;
+
// tran_scheme is the transport scheme, such as "tcp" or "inproc".
const char *tran_scheme;
@@ -32,6 +38,17 @@ struct nni_tran {
void (*tran_fini)(void);
};
+// We quite intentionally use a signature where the upper word is nonzero,
+// which ensures that if we get garbage we will reject it. This is more
+// likely to mismatch than all zero bytes would. The actual version is
+// stored in the lower word; this is not semver -- the numbers are just
+// increasing - we doubt it will increase more than a handful of times
+// during the life of the project. If we add a new version, please keep
+// the old version around -- it may be possible to automatically convert
+// older versions in the future.
+#define NNI_TRANSPORT_V0 0x54520000
+#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V0
+
// Endpoint operations are called by the socket in a protocol-independent
// fashion. The socket makes individual calls, which are expected to block
// if appropriate (except for destroy). Endpoints are unable to call back