aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-01-16 12:07:45 -0800
committerGarrett D'Amore <garrett@damore.org>2018-01-16 14:29:38 -0800
commit02e6153236ae744fb614fcd14184924ec85c2993 (patch)
tree6b41ca972d60e758c65c1adc0621500a92003c86 /src/transport
parentbbf012364d9f1482b16c97b8bfd2fd07130446ca (diff)
downloadnng-02e6153236ae744fb614fcd14184924ec85c2993.tar.gz
nng-02e6153236ae744fb614fcd14184924ec85c2993.tar.bz2
nng-02e6153236ae744fb614fcd14184924ec85c2993.zip
fixes #206 Want NNG_OPT_TLS_VERIFIED option
It is useful to have support for validating that a peer *was* verified, especially in the presence of optional validation. We have added a property that does this, NNG_OPT_TLS_VERIFIED. Further, all the old NNG_OPT_WSS_TLS_* property names have also been renamed to generic NNG_OPT_TLS property names, which have been moved to nng.h to facilitate reuse and sharing, with the comments moved and corrected as well. Finally, the man pages have been updated, with substantial improvements to the nng_ws man page in particular.
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/tls/tls.c2
-rw-r--r--src/transport/tls/tls.h12
-rw-r--r--src/transport/ws/websocket.c67
-rw-r--r--src/transport/ws/websocket.h54
4 files changed, 41 insertions, 94 deletions
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index 408ff50c..05d477b5 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -855,7 +855,7 @@ tls_getopt_verified(void *arg, void *v, size_t *szp)
static nni_tran_pipe_option nni_tls_pipe_options[] = {
{ NNG_OPT_LOCADDR, nni_tls_pipe_getopt_locaddr },
{ NNG_OPT_REMADDR, nni_tls_pipe_getopt_remaddr },
- { NNG_OPT_TLS_AUTH_VERIFIED, tls_getopt_verified },
+ { NNG_OPT_TLS_VERIFIED, tls_getopt_verified },
// terminate list
{ NULL, NULL }
};
diff --git a/src/transport/tls/tls.h b/src/transport/tls/tls.h
index 25edfa3a..a3fa0eb9 100644
--- a/src/transport/tls/tls.h
+++ b/src/transport/tls/tls.h
@@ -15,16 +15,4 @@
NNG_DECL int nng_tls_register(void);
-// TLS options. Note that these can only be set *before* the endpoint is
-// started. Once started, it is no longer possible to alter the TLS
-// configuration.
-
-// NNG_OPT_TLS_AUTH_VERIFIED is a boolean that can be read on pipes,
-// indicating whether the peer certificate is verified.
-#define NNG_OPT_TLS_AUTH_VERIFIED "tls:auth-verified"
-
-// NNG_OPT_TLS_CONFIG is used to access the underlying configuration
-// (an nng_tls_config *).
-#define NNG_OPT_TLS_CONFIG "tls:config"
-
#endif // NNG_TRANSPORT_TLS_TLS_H
diff --git a/src/transport/ws/websocket.c b/src/transport/ws/websocket.c
index 16cdf47b..a06910d3 100644
--- a/src/transport/ws/websocket.c
+++ b/src/transport/ws/websocket.c
@@ -43,6 +43,7 @@ struct ws_ep {
nni_ws_listener *listener;
nni_ws_dialer * dialer;
nni_list headers; // to send, res or req
+ bool started;
};
struct ws_pipe {
@@ -261,16 +262,13 @@ ws_hook(void *arg, nni_http_req *req, nni_http_res *res)
// Eventually we'll want user customizable hooks.
// For now we just set the headers we want.
- nni_mtx_lock(&ep->mtx);
NNI_LIST_FOREACH (&ep->headers, h) {
int rv;
- rv = nni_http_req_set_header(req, h->name, h->value);
+ rv = nni_http_res_set_header(res, h->name, h->value);
if (rv != 0) {
- nni_mtx_unlock(&ep->mtx);
return (rv);
}
}
- nni_mtx_unlock(&ep->mtx);
return (0);
}
@@ -278,9 +276,13 @@ static int
ws_ep_bind(void *arg)
{
ws_ep *ep = arg;
+ int rv;
nni_ws_listener_hook(ep->listener, ws_hook, ep);
- return (nni_ws_listener_listen(ep->listener));
+ if ((rv = nni_ws_listener_listen(ep->listener)) == 0) {
+ ep->started = true;
+ }
+ return (rv);
}
static void
@@ -320,28 +322,29 @@ static void
ws_ep_connect(void *arg, nni_aio *aio)
{
ws_ep * ep = arg;
- int rv;
+ int rv = 0;
ws_hdr *h;
+ if (!ep->started) {
+ NNI_LIST_FOREACH (&ep->headers, h) {
+ rv = nni_ws_dialer_header(
+ ep->dialer, h->name, h->value);
+ if (rv != 0) {
+ nni_aio_finish_error(aio, rv);
+ return;
+ }
+ }
+ }
+
nni_mtx_lock(&ep->mtx);
NNI_ASSERT(nni_list_empty(&ep->aios));
- // If we can't start, then its dying and we can't report
- // either.
+ // If we can't start, then its dying and we can't report either.
if ((rv = nni_aio_start(aio, ws_ep_cancel, ep)) != 0) {
nni_mtx_unlock(&ep->mtx);
return;
}
-
- NNI_LIST_FOREACH (&ep->headers, h) {
- rv = nni_ws_dialer_header(ep->dialer, h->name, h->value);
- if (rv != 0) {
- nni_aio_finish_error(aio, rv);
- nni_mtx_unlock(&ep->mtx);
- return;
- }
- }
-
+ ep->started = true;
nni_list_append(&ep->aios, aio);
nni_ws_dialer_dial(ep->dialer, ep->connaio);
nni_mtx_unlock(&ep->mtx);
@@ -374,6 +377,10 @@ ws_ep_setopt_headers(ws_ep *ep, const void *v, size_t sz)
return (0);
}
+ if (ep->started) {
+ return (NNG_EBUSY);
+ }
+
NNI_LIST_INIT(&l, ws_hdr, node);
if ((dupstr = nni_strdup(v)) == NULL) {
return (NNG_ENOMEM);
@@ -418,7 +425,6 @@ ws_ep_setopt_headers(ws_ep *ep, const void *v, size_t sz)
name = nl;
}
- nni_mtx_lock(&ep->mtx);
while ((h = nni_list_first(&ep->headers)) != NULL) {
nni_list_remove(&ep->headers, h);
nni_strfree(h->name);
@@ -429,7 +435,6 @@ ws_ep_setopt_headers(ws_ep *ep, const void *v, size_t sz)
nni_list_remove(&l, h);
nni_list_append(&ep->headers, h);
}
- nni_mtx_unlock(&ep->mtx);
rv = 0;
done:
@@ -532,6 +537,13 @@ ws_pipe_getopt_reqhdrs(void *arg, void *v, size_t *szp)
return (nni_getopt_str(s, v, szp));
}
+static int
+ws_pipe_getopt_tls_verified(void *arg, void *v, size_t *szp)
+{
+ ws_pipe *p = arg;
+ return (nni_getopt_int(nni_ws_tls_verified(p->ws) ? 1 : 0, v, szp));
+}
+
static nni_tran_pipe_option ws_pipe_options[] = {
// clang-format off
@@ -539,6 +551,7 @@ static nni_tran_pipe_option ws_pipe_options[] = {
{ NNG_OPT_REMADDR, ws_pipe_getopt_remaddr },
{ NNG_OPT_WS_REQUEST_HEADERS, ws_pipe_getopt_reqhdrs },
{ NNG_OPT_WS_RESPONSE_HEADERS, ws_pipe_getopt_reshdrs },
+ { NNG_OPT_TLS_VERIFIED, ws_pipe_getopt_tls_verified },
// clang-format on
// terminate list
@@ -931,37 +944,37 @@ static nni_tran_ep_option wss_ep_options[] = {
.eo_setopt = ws_ep_setopt_recvmaxsz,
},
{
- .eo_name = NNG_OPT_WSS_REQUEST_HEADERS,
+ .eo_name = NNG_OPT_WS_REQUEST_HEADERS,
.eo_getopt = NULL,
.eo_setopt = ws_ep_setopt_reqhdrs,
},
{
- .eo_name = NNG_OPT_WSS_RESPONSE_HEADERS,
+ .eo_name = NNG_OPT_WS_RESPONSE_HEADERS,
.eo_getopt = NULL,
.eo_setopt = ws_ep_setopt_reshdrs,
},
{
- .eo_name = NNG_OPT_WSS_TLS_CONFIG,
+ .eo_name = NNG_OPT_TLS_CONFIG,
.eo_getopt = wss_ep_getopt_tlsconfig,
.eo_setopt = wss_ep_setopt_tlsconfig,
},
{
- .eo_name = NNG_OPT_WSS_TLS_CERT_KEY_FILE,
+ .eo_name = NNG_OPT_TLS_CERT_KEY_FILE,
.eo_getopt = NULL,
.eo_setopt = wss_ep_setopt_tls_cert_key_file,
},
{
- .eo_name = NNG_OPT_WSS_TLS_CA_FILE,
+ .eo_name = NNG_OPT_TLS_CA_FILE,
.eo_getopt = NULL,
.eo_setopt = wss_ep_setopt_tls_ca_file,
},
{
- .eo_name = NNG_OPT_WSS_TLS_AUTH_MODE,
+ .eo_name = NNG_OPT_TLS_AUTH_MODE,
.eo_getopt = NULL,
.eo_setopt = wss_ep_setopt_tls_auth_mode,
},
{
- .eo_name = NNG_OPT_WSS_TLS_SERVER_NAME,
+ .eo_name = NNG_OPT_TLS_SERVER_NAME,
.eo_getopt = NULL,
.eo_setopt = wss_ep_setopt_tls_server_name,
},
diff --git a/src/transport/ws/websocket.h b/src/transport/ws/websocket.h
index 1f261067..76e94c3e 100644
--- a/src/transport/ws/websocket.h
+++ b/src/transport/ws/websocket.h
@@ -23,60 +23,6 @@ NNG_DECL int nng_ws_register(void);
// response headers, formatted as CRLF terminated lines.
#define NNG_OPT_WS_RESPONSE_HEADERS "ws:response-headers"
-// NNG_OPT_WSS_TLS_CONFIG is a pointer to a an nng_tls_config
-// object. This property is only available for wss:// style
-// endpoints. Note that when configuring the object, a hold
-// is placed on the TLS configuration. When retrieving the
-// object, no hold is placed, and so the caller must take care
-// not to use the configuration object after the endpoint it
-// is associated with is removed. Furthermore, as this is a
-// pointer, applications must take care to pass only valid
-// data -- incorrect pointer values will lead to undefined
-// behavior.
-#define NNG_OPT_WSS_TLS_CONFIG "wss:tls-config"
-
-// NNG_OPT_WSS_TLS_CERT_KEY_FILE names a single file that
-// contains a certificate and key identifying ourself. This
-// is a write-only value. Listeners can call this multiple
-// times for different keys/certs corresponding to different
-// algorithms, whereas clients only get one. The file must
-// contain both cert and key as PEM blocks, and the key must
-// not be encrypted. (If more flexibility is needed, use the
-// TLS configuration directly.) Note that TLS configuration
-// cannot be changed if the listener, or any other from the same
-// server and port, is already started.
-#define NNG_OPT_WSS_TLS_CERT_KEY_FILE "wss:tls-cert-key-file"
-
-// NNG_OPT_WSS_TLS_CA_FILE names a single file that
-// contains certificate(s) for a CA, and optinally CRLs. This
-// is a write-only value. Listeners can call this multiple
-// times for different keys/certs corresponding to different
-// algorithms, whereas clients only get one. The file must
-// contain certs as PEM blocks, and may contain CRLs as PEM
-// as well. (If more flexibility is needed, use the
-// TLS configuration directly.) Note that TLS configuration
-// cannot be changed if the listener, or any other from the same
-// server and port, is already started.
-#define NNG_OPT_WSS_TLS_CA_FILE "wss:tls-ca-file"
-
-// NNG_OPT_WSS_TLS_AUTH_MODE is a write-only integer (int) option
-// that specifies whether the peer is verified or not. The option
-// can take one of the values of NNG_TLS_AUTH_MODE_NONE,
-// NNG_TLS_AUTH_MODE_OPTIONAL, or NNG_TLS_AUTH_MODE_REQUIRED.
-// The default is NNG_TLS_AUTH_MODE_NONE for listeners, and
-// NNG_TLS_AUTH_MODE_REQUIRED for dialers.
-#define NNG_OPT_WSS_TLS_AUTH_MODE "wss:tls-auth-mode"
-
-// NNG_OPT_WSS_TLS_SERVER_NAME is a write-only string that can be
-// set on dialers to check the CN of the server for a match. This
-// can also affect SNI (server name indication).
-#define NNG_OPT_WSS_TLS_SERVER_NAME "wss:tls-server-name"
-
-// NNG_OPT_WSS_TLS_VERIFIED returns a single integer, indicating
-// whether the peer was verified or not. This is a read-only value
-// available only on pipes.
-#define NNT_OPT_WSS_TLS_VERIFIED "wss:tls-verified"
-
// These aliases are for WSS naming consistency.
#define NNG_OPT_WSS_REQUEST_HEADERS NNG_OPT_WS_REQUEST_HEADERS
#define NNG_OPT_WSS_RESPONSE_HEADERS NNG_OPT_WS_RESPONSE_HEADERS