aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-12-29 21:28:49 -0800
committerGarrett D'Amore <garrett@damore.org>2018-12-31 17:10:04 -0800
commita73ff5363eae228009413872b05aff758a46c5ca (patch)
treed5fa805188f915fc94c9b80d4f5cbbb96e6a4551 /src
parente0fff1f9c45f5486fc2e7eeb49b4462c3bb2dad4 (diff)
downloadnng-a73ff5363eae228009413872b05aff758a46c5ca.tar.gz
nng-a73ff5363eae228009413872b05aff758a46c5ca.tar.bz2
nng-a73ff5363eae228009413872b05aff758a46c5ca.zip
fixes #825 TCP public API should use generic setopt/getopt
This changes much of the internal API for TCP option handling, and includes hooks for some of this in various consumers. Note that the consumers still need to have additional work done to complete them, which will be part of providing public "raw" TLS and WebSocket APIs. We would also like to finish addressing the call sites of nni_tcp_listener_start() that assume the sockaddr is modified -- it would be superior to use the NNG_OPT_LOCADDR option. Thaat will be addressed in a follow up PR.
Diffstat (limited to 'src')
-rw-r--r--src/core/platform.h43
-rw-r--r--src/platform/posix/posix_tcp.h10
-rw-r--r--src/platform/posix/posix_tcpconn.c159
-rw-r--r--src/platform/posix/posix_tcpdial.c207
-rw-r--r--src/platform/posix/posix_tcplisten.c116
-rw-r--r--src/platform/windows/win_impl.h4
-rw-r--r--src/platform/windows/win_tcp.h13
-rw-r--r--src/platform/windows/win_tcpconn.c140
-rw-r--r--src/platform/windows/win_tcpdial.c205
-rw-r--r--src/platform/windows/win_tcplisten.c122
-rw-r--r--src/supplemental/http/http_api.h15
-rw-r--r--src/supplemental/http/http_conn.c134
-rw-r--r--src/supplemental/tcp/tcp.c45
-rw-r--r--src/supplemental/tls/mbedtls/tls.c66
-rw-r--r--src/supplemental/tls/none/tls.c42
-rw-r--r--src/supplemental/tls/tls_api.h20
-rw-r--r--src/supplemental/websocket/websocket.c55
-rw-r--r--src/supplemental/websocket/websocket.h23
-rw-r--r--src/transport/tcp/tcp.c226
-rw-r--r--src/transport/tls/tls.c110
-rw-r--r--src/transport/ws/websocket.c83
21 files changed, 1236 insertions, 602 deletions
diff --git a/src/core/platform.h b/src/core/platform.h
index 58955a3a..18107120 100644
--- a/src/core/platform.h
+++ b/src/core/platform.h
@@ -263,6 +263,18 @@ extern int nni_tcp_conn_set_nodelay(nni_tcp_conn *, bool);
// keepalive probes. Tuning of these keepalives is currently unsupported.
extern int nni_tcp_conn_set_keepalive(nni_tcp_conn *, bool);
+// nni_tcp_conn_setopt is like setsockopt, but uses string names. These
+// are the same names from the TCP transport, generally. Examples are
+// NNG_OPT_TCP_NODELAY and NNG_OPT_TCP_KEEPALIVE.
+extern int nni_tcp_conn_setopt(
+ nni_tcp_conn *, const char *, const void *, size_t, nni_type);
+
+// nni_tcp_conn_getopt is like getsockopt, but uses string names.
+// We support NNG_OPT_REMADDR and NNG_OPT_LOCADDR (with argument type
+// nng_sockaddr), and NNG_OPT_TCP_NODELAY and NNG_OPT_TCP_KEEPALIVE.
+extern int nni_tcp_conn_getopt(
+ nni_tcp_conn *, const char *, void *, size_t *, nni_type);
+
// nni_tcp_dialer_init creates a new dialer object.
extern int nni_tcp_dialer_init(nni_tcp_dialer **);
@@ -275,21 +287,24 @@ extern void nni_tcp_dialer_fini(nni_tcp_dialer *);
// connection will be aborted.
extern void nni_tcp_dialer_close(nni_tcp_dialer *);
-// nni_tcp_dialer_set_src_addr sets the source address to use for outgoing
-// connections. Only the IP (or IPv6) address may be specified; the port
-// must be zero. This must be called before calling nni_tcp_dialer_dial.
-// The source address must be associated with one of the addresses on the
-// local system -- this is not checked until bind() is called just prior to
-// the connect() call. Likewise the address family must be the same as the
-// address used when dialing, or errors will occur.
-extern int nni_tcp_dialer_set_src_addr(nni_tcp_dialer *, const nng_sockaddr *);
-
// nni_tcp_dialer_dial attempts to create an outgoing connection,
// asynchronously, to the address specified. On success, the first (and only)
// output will be an nni_tcp_conn * associated with the remote server.
extern void nni_tcp_dialer_dial(
nni_tcp_dialer *, const nni_sockaddr *, nni_aio *);
+// nni_tcp_dialer_getopt gets an option from the dialer.
+extern int nni_tcp_dialer_setopt(
+ nni_tcp_dialer *, const char *, const void *, size_t, nni_type);
+
+// nni_tcp_dialer_setopt sets an option on the dialer. There is special
+// support for NNG_OPT_LOCADDR, which will be the source address (if legal)
+// for new connections, except that the port will be ignored. The
+// NNG_OPT_TCP_NODELAY and NNG_OPT_TCP_KEEPALIVE options work to set the
+// initial values of those options on newly created connections.
+extern int nni_tcp_dialer_getopt(
+ nni_tcp_dialer *, const char *, void *, size_t *, nni_type);
+
// nni_tcp_listener_init creates a new listener object, unbound.
extern int nni_tcp_listener_init(nni_tcp_listener **);
@@ -313,6 +328,16 @@ extern int nni_tcp_listener_listen(nni_tcp_listener *, nni_sockaddr *);
// associated with the remote peer.
extern void nni_tcp_listener_accept(nni_tcp_listener *, nni_aio *);
+// nni_tcp_listener_getopt gets an option from the listener.
+extern int nni_tcp_listener_setopt(
+ nni_tcp_listener *, const char *, const void *, size_t, nni_type);
+
+// nni_tcp_listener_setopt sets an option on the listener. The most common
+// use for this is to retrieve the setting of the NNG_OPT_TCP_LOCADDR
+// address after binding to wild card port (0).
+extern int nni_tcp_listener_getopt(
+ nni_tcp_listener *, const char *, void *, size_t *, nni_type);
+
// nni_ntop obtains the IP address for the socket (enclosing it
// in brackets if it is IPv6) and port. Enough space for both must
// be present (48 bytes and 6 bytes each), although if either is NULL then
diff --git a/src/platform/posix/posix_tcp.h b/src/platform/posix/posix_tcp.h
index 633a63b5..788fcbf8 100644
--- a/src/platform/posix/posix_tcp.h
+++ b/src/platform/posix/posix_tcp.h
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,7 +11,6 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_POSIX
#include "platform/posix/posix_aio.h"
struct nni_tcp_conn {
@@ -27,6 +27,8 @@ struct nni_tcp_conn {
struct nni_tcp_dialer {
nni_list connq; // pending connections
bool closed;
+ bool nodelay;
+ bool keepalive;
struct sockaddr_storage src;
size_t srclen;
nni_mtx mtx;
@@ -37,10 +39,10 @@ struct nni_tcp_listener {
nni_list acceptq;
bool started;
bool closed;
+ bool nodelay;
+ bool keepalive;
nni_mtx mtx;
};
extern int nni_posix_tcp_conn_init(nni_tcp_conn **, nni_posix_pfd *);
-extern void nni_posix_tcp_conn_start(nni_tcp_conn *);
-
-#endif // NNG_PLATFORM_POSIX
+extern void nni_posix_tcp_conn_start(nni_tcp_conn *, int, int);
diff --git a/src/platform/posix/posix_tcpconn.c b/src/platform/posix/posix_tcpconn.c
index 788c4e9f..a10e102f 100644
--- a/src/platform/posix/posix_tcpconn.c
+++ b/src/platform/posix/posix_tcpconn.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,8 +11,6 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_POSIX
-
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -369,6 +368,152 @@ nni_tcp_conn_set_nodelay(nni_tcp_conn *c, bool nodelay)
return (0);
}
+static int
+tcp_conn_get_peername(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn * c = arg;
+ struct sockaddr_storage ss;
+ socklen_t sslen = sizeof(ss);
+ int fd = nni_posix_pfd_fd(c->pfd);
+ int rv;
+ nng_sockaddr sa;
+
+ if (getpeername(fd, (void *) &ss, &sslen) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ if ((rv = nni_posix_sockaddr2nn(&sa, &ss)) == 0) {
+ rv = nni_copyout_sockaddr(&sa, buf, szp, t);
+ }
+ return (rv);
+}
+
+static int
+tcp_conn_get_sockname(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn * c = arg;
+ struct sockaddr_storage ss;
+ socklen_t sslen = sizeof(ss);
+ int fd = nni_posix_pfd_fd(c->pfd);
+ int rv;
+ nng_sockaddr sa;
+
+ if (getsockname(fd, (void *) &ss, &sslen) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ if ((rv = nni_posix_sockaddr2nn(&sa, &ss)) == 0) {
+ rv = nni_copyout_sockaddr(&sa, buf, szp, t);
+ }
+ return (rv);
+}
+
+static int
+tcp_conn_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ int fd;
+ bool b;
+ int val;
+ int rv;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (c == NULL)) {
+ return (rv);
+ }
+ val = b ? 1 : 0;
+ fd = nni_posix_pfd_fd(c->pfd);
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ return (0);
+}
+
+static int
+tcp_conn_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ int fd;
+ bool b;
+ int val;
+ int rv;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (c == NULL)) {
+ return (rv);
+ }
+ val = b ? 1 : 0;
+ fd = nni_posix_pfd_fd(c->pfd);
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 0) {
+ return (nni_plat_errno(errno));
+ }
+ return (0);
+}
+
+static int
+tcp_conn_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ int fd = nni_posix_pfd_fd(c->pfd);
+ int val = 0;
+ socklen_t valsz = sizeof(val);
+
+ if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, &valsz) != 0) {
+ return (nni_plat_errno(errno));
+ }
+
+ return (nni_copyout_bool(val, buf, szp, t));
+}
+
+static int
+tcp_conn_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ int fd = nni_posix_pfd_fd(c->pfd);
+ int val = 0;
+ socklen_t valsz = sizeof(val);
+
+ if (getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, &valsz) != 0) {
+ return (nni_plat_errno(errno));
+ }
+
+ return (nni_copyout_bool(val, buf, szp, t));
+}
+
+static const nni_option tcp_conn_options[] = {
+ {
+ .o_name = NNG_OPT_REMADDR,
+ .o_get = tcp_conn_get_peername,
+ },
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = tcp_conn_get_sockname,
+ },
+ {
+ .o_name = NNG_OPT_TCP_NODELAY,
+ .o_get = tcp_conn_get_nodelay,
+ .o_set = tcp_conn_set_nodelay,
+ },
+ {
+ .o_name = NNG_OPT_TCP_KEEPALIVE,
+ .o_get = tcp_conn_get_keepalive,
+ .o_set = tcp_conn_set_keepalive,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+int
+nni_tcp_conn_getopt(
+ nni_tcp_conn *c, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_getopt(tcp_conn_options, name, c, buf, szp, t));
+}
+
+int
+nni_tcp_conn_setopt(
+ nni_tcp_conn *c, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ return (nni_setopt(tcp_conn_options, name, c, buf, sz, t));
+}
+
int
nni_posix_tcp_conn_init(nni_tcp_conn **cp, nni_posix_pfd *pfd)
{
@@ -390,8 +535,14 @@ nni_posix_tcp_conn_init(nni_tcp_conn **cp, nni_posix_pfd *pfd)
}
void
-nni_posix_tcp_conn_start(nni_tcp_conn *c)
+nni_posix_tcp_conn_start(nni_tcp_conn *c, int nodelay, int keepalive)
{
+ // COnfigure the initial socket options.
+ (void) setsockopt(
+ c->pfd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(int));
+ (void) setsockopt(
+ c->pfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(int));
+
nni_posix_pfd_set_cb(c->pfd, tcp_conn_cb, c);
}
@@ -407,5 +558,3 @@ nni_tcp_conn_fini(nni_tcp_conn *c)
NNI_FREE_STRUCT(c);
}
-
-#endif // NNG_PLATFORM_POSIX
diff --git a/src/platform/posix/posix_tcpdial.c b/src/platform/posix/posix_tcpdial.c
index 918ee9ba..cfb3482c 100644
--- a/src/platform/posix/posix_tcpdial.c
+++ b/src/platform/posix/posix_tcpdial.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,8 +11,6 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_POSIX
-
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -105,6 +104,8 @@ tcp_dialer_cb(nni_posix_pfd *pfd, int ev, void *arg)
nni_tcp_dialer *d = c->dialer;
nni_aio * aio;
int rv;
+ int ka;
+ int nd;
nni_mtx_lock(&d->mtx);
aio = c->dial_aio;
@@ -135,6 +136,9 @@ tcp_dialer_cb(nni_posix_pfd *pfd, int ev, void *arg)
c->dial_aio = NULL;
nni_aio_list_remove(aio);
nni_aio_set_prov_extra(aio, 0, NULL);
+ nd = d->nodelay ? 1 : 0;
+ ka = d->keepalive ? 1 : 0;
+
nni_mtx_unlock(&d->mtx);
if (rv != 0) {
@@ -144,51 +148,11 @@ tcp_dialer_cb(nni_posix_pfd *pfd, int ev, void *arg)
return;
}
- nni_posix_tcp_conn_start(c);
+ nni_posix_tcp_conn_start(c, nd, ka);
nni_aio_set_output(aio, 0, c);
nni_aio_finish(aio, 0, 0);
}
-int
-nni_tcp_dialer_set_src_addr(nni_tcp_dialer *d, const nni_sockaddr *sa)
-{
- struct sockaddr_storage ss;
- struct sockaddr_in * sin;
- struct sockaddr_in6 * sin6;
- size_t sslen;
-
- if ((sslen = nni_posix_nn2sockaddr(&ss, sa)) == 0) {
- return (NNG_EADDRINVAL);
- }
- // Ensure we are either IPv4 or IPv6, and port is not set. (We
- // do not allow binding to a specific port.)
- switch (ss.ss_family) {
- case AF_INET:
- sin = (void *) &ss;
- if (sin->sin_port != 0) {
- return (NNG_EADDRINVAL);
- }
- break;
- case AF_INET6:
- sin6 = (void *) &ss;
- if (sin6->sin6_port != 0) {
- return (NNG_EADDRINVAL);
- }
- break;
- default:
- return (NNG_EADDRINVAL);
- }
- nni_mtx_lock(&d->mtx);
- if (d->closed) {
- nni_mtx_unlock(&d->mtx);
- return (NNG_ECLOSED);
- }
- d->src = ss;
- d->srclen = sslen;
- nni_mtx_unlock(&d->mtx);
- return (0);
-}
-
// We don't give local address binding support. Outbound dialers always
// get an ephemeral port.
void
@@ -200,6 +164,8 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio)
size_t sslen;
int fd;
int rv;
+ int ka;
+ int nd;
if (nni_aio_begin(aio) != 0) {
return;
@@ -263,8 +229,10 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio)
// Immediate connect, cool! This probably only happens
// on loopback, and probably not on every platform.
nni_aio_set_prov_extra(aio, 0, NULL);
+ nd = d->nodelay ? 1 : 0;
+ ka = d->keepalive ? 1 : 0;
nni_mtx_unlock(&d->mtx);
- nni_posix_tcp_conn_start(c);
+ nni_posix_tcp_conn_start(c, nd, ka);
nni_aio_set_output(aio, 0, c);
nni_aio_finish(aio, 0, 0);
return;
@@ -276,4 +244,153 @@ error:
nni_aio_finish_error(aio, rv);
}
-#endif // NNG_PLATFORM_POSIX
+static int
+tcp_dialer_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_dialer *d = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (d == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&d->mtx);
+ d->nodelay = b;
+ nni_mtx_unlock(&d->mtx);
+ return (0);
+}
+
+static int
+tcp_dialer_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_dialer *d = arg;
+ nni_mtx_lock(&d->mtx);
+ b = d->nodelay;
+ nni_mtx_unlock(&d->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_dialer_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_dialer *d = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (d == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&d->mtx);
+ d->keepalive = b;
+ nni_mtx_unlock(&d->mtx);
+ return (0);
+}
+
+static int
+tcp_dialer_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_dialer *d = arg;
+ nni_mtx_lock(&d->mtx);
+ b = d->keepalive;
+ nni_mtx_unlock(&d->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_dialer_get_locaddr(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_dialer *d = arg;
+ nng_sockaddr sa;
+
+ nni_mtx_lock(&d->mtx);
+ if (nni_posix_sockaddr2nn(&sa, &d->src) != 0) {
+ sa.s_family = NNG_AF_UNSPEC;
+ }
+ nni_mtx_unlock(&d->mtx);
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
+}
+
+static int
+tcp_dialer_set_locaddr(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_dialer * d = arg;
+ nng_sockaddr sa;
+ struct sockaddr_storage ss;
+ struct sockaddr_in * sin;
+ struct sockaddr_in6 * sin6;
+ size_t sslen;
+ int rv;
+
+ if ((rv = nni_copyin_sockaddr(&sa, buf, sz, t)) != 0) {
+ return (rv);
+ }
+ if ((sslen = nni_posix_nn2sockaddr(&ss, &sa)) == 0) {
+ return (NNG_EADDRINVAL);
+ }
+ // Ensure we are either IPv4 or IPv6, and port is not set. (We
+ // do not allow binding to a specific port.)
+ switch (ss.ss_family) {
+ case AF_INET:
+ sin = (void *) &ss;
+ if (sin->sin_port != 0) {
+ return (NNG_EADDRINVAL);
+ }
+ break;
+ case AF_INET6:
+ sin6 = (void *) &ss;
+ if (sin6->sin6_port != 0) {
+ return (NNG_EADDRINVAL);
+ }
+ break;
+ default:
+ return (NNG_EADDRINVAL);
+ }
+ if (d != NULL) {
+ nni_mtx_lock(&d->mtx);
+ if (d->closed) {
+ nni_mtx_unlock(&d->mtx);
+ return (NNG_ECLOSED);
+ }
+ d->src = ss;
+ d->srclen = sslen;
+ nni_mtx_unlock(&d->mtx);
+ }
+ return (0);
+}
+
+static const nni_option tcp_dialer_options[] = {
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = tcp_dialer_get_locaddr,
+ .o_set = tcp_dialer_set_locaddr,
+ },
+ {
+ .o_name = NNG_OPT_TCP_NODELAY,
+ .o_get = tcp_dialer_get_nodelay,
+ .o_set = tcp_dialer_set_nodelay,
+ },
+ {
+ .o_name = NNG_OPT_TCP_KEEPALIVE,
+ .o_get = tcp_dialer_get_keepalive,
+ .o_set = tcp_dialer_set_keepalive,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+int
+nni_tcp_dialer_getopt(
+ nni_tcp_dialer *d, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_getopt(tcp_dialer_options, name, d, buf, szp, t));
+}
+
+int
+nni_tcp_dialer_setopt(nni_tcp_dialer *d, const char *name, const void *buf,
+ size_t sz, nni_type t)
+{
+ return (nni_setopt(tcp_dialer_options, name, d, buf, sz, t));
+}
diff --git a/src/platform/posix/posix_tcplisten.c b/src/platform/posix/posix_tcplisten.c
index bc414cd0..82334431 100644
--- a/src/platform/posix/posix_tcplisten.c
+++ b/src/platform/posix/posix_tcplisten.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,8 +11,6 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_POSIX
-
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -82,6 +81,8 @@ tcp_listener_doaccept(nni_tcp_listener *l)
int newfd;
int fd;
int rv;
+ int nd;
+ int ka;
nni_posix_pfd *pfd;
nni_tcp_conn * c;
@@ -139,8 +140,10 @@ tcp_listener_doaccept(nni_tcp_listener *l)
continue;
}
+ ka = l->keepalive ? 1 : 0;
+ nd = l->nodelay ? 1 : 0;
nni_aio_list_remove(aio);
- nni_posix_tcp_conn_start(c);
+ nni_posix_tcp_conn_start(c, nd, ka);
nni_aio_set_output(aio, 0, c);
nni_aio_finish(aio, 0, 0);
}
@@ -315,4 +318,109 @@ nni_tcp_listener_accept(nni_tcp_listener *l, nni_aio *aio)
nni_mtx_unlock(&l->mtx);
}
-#endif // NNG_PLATFORM_POSIX
+static int
+tcp_listener_get_locaddr(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_listener *l = arg;
+ nng_sockaddr sa;
+ nni_mtx_lock(&l->mtx);
+ if (l->started) {
+ struct sockaddr_storage ss;
+ socklen_t len = sizeof(ss);
+ (void) getsockname(
+ nni_posix_pfd_fd(l->pfd), (void *) &ss, &len);
+ (void) nni_posix_sockaddr2nn(&sa, &ss);
+ } else {
+ sa.s_family = NNG_AF_UNSPEC;
+ }
+ nni_mtx_unlock(&l->mtx);
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
+}
+
+static int
+tcp_listener_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_listener *l = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (l == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&l->mtx);
+ l->nodelay = b;
+ nni_mtx_unlock(&l->mtx);
+ return (0);
+}
+
+static int
+tcp_listener_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_listener *l = arg;
+ nni_mtx_lock(&l->mtx);
+ b = l->nodelay;
+ nni_mtx_unlock(&l->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_listener_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_listener *l = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (l == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&l->mtx);
+ l->keepalive = b;
+ nni_mtx_unlock(&l->mtx);
+ return (0);
+}
+
+static int
+tcp_listener_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_listener *l = arg;
+ nni_mtx_lock(&l->mtx);
+ b = l->keepalive;
+ nni_mtx_unlock(&l->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static const nni_option tcp_listener_options[] = {
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = tcp_listener_get_locaddr,
+ },
+ {
+ .o_name = NNG_OPT_TCP_NODELAY,
+ .o_set = tcp_listener_set_nodelay,
+ .o_get = tcp_listener_get_nodelay,
+ },
+ {
+ .o_name = NNG_OPT_TCP_KEEPALIVE,
+ .o_set = tcp_listener_set_keepalive,
+ .o_get = tcp_listener_get_keepalive,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+int
+nni_tcp_listener_getopt(
+ nni_tcp_listener *l, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_getopt(tcp_listener_options, name, l, buf, szp, t));
+}
+
+int
+nni_tcp_listener_setopt(nni_tcp_listener *l, const char *name, const void *buf,
+ size_t sz, nni_type t)
+{
+ return (nni_setopt(tcp_listener_options, name, l, buf, sz, t));
+}
diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h
index fd4c9343..cd15804a 100644
--- a/src/platform/windows/win_impl.h
+++ b/src/platform/windows/win_impl.h
@@ -75,9 +75,7 @@ struct nni_plat_flock {
extern int nni_win_error(int);
-extern int nni_win_tcp_conn_init(nni_tcp_conn **, SOCKET);
-extern void nni_win_tcp_conn_set_addrs(
- nni_tcp_conn *, const SOCKADDR_STORAGE *, const SOCKADDR_STORAGE *);
+extern int nni_win_tcp_conn_init(nni_tcp_conn **, SOCKET);
extern int nni_win_io_sysinit(void);
extern void nni_win_io_sysfini(void);
diff --git a/src/platform/windows/win_tcp.h b/src/platform/windows/win_tcp.h
index 9c7a4d0e..96854ac1 100644
--- a/src/platform/windows/win_tcp.h
+++ b/src/platform/windows/win_tcp.h
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -15,7 +16,7 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_WINDOWS
+#include <nng/transport/tcp/tcp.h>
struct nni_tcp_conn {
SOCKET s;
@@ -42,6 +43,8 @@ struct nni_tcp_dialer {
LPFN_CONNECTEX connectex; // looked up name via ioctl
nni_list aios; // in flight connections
bool closed;
+ bool nodelay; // initial value for child conns
+ bool keepalive; // initial value for child conns
SOCKADDR_STORAGE src;
size_t srclen;
nni_mtx mtx;
@@ -53,6 +56,8 @@ struct nni_tcp_listener {
nni_list aios;
bool closed;
bool started;
+ bool nodelay; // initial value for child conns
+ bool keepalive; // initial value for child conns
LPFN_ACCEPTEX acceptex;
LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
SOCKADDR_STORAGE ss;
@@ -60,10 +65,6 @@ struct nni_tcp_listener {
nni_reap_item reap;
};
-extern int nni_win_tcp_conn_init(nni_tcp_conn **, SOCKET);
-extern void nni_win_tcp_conn_set_addrs(
- nni_tcp_conn *, const SOCKADDR_STORAGE *, const SOCKADDR_STORAGE *);
-
-#endif // NNG_PLATFORM_WINDOWS
+extern int nni_win_tcp_conn_init(nni_tcp_conn **, SOCKET);
#endif // NNG_PLATFORM_WIN_WINTCP_H
diff --git a/src/platform/windows/win_tcpconn.c b/src/platform/windows/win_tcpconn.c
index 68c72b9b..54d22dea 100644
--- a/src/platform/windows/win_tcpconn.c
+++ b/src/platform/windows/win_tcpconn.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -12,8 +13,6 @@
#include "win_tcp.h"
-#ifdef NNG_PLATFORM_WINDOWS
-
#include <malloc.h>
#include <stdio.h>
@@ -293,14 +292,6 @@ nni_win_tcp_conn_init(nni_tcp_conn **connp, SOCKET s)
}
void
-nni_win_tcp_conn_set_addrs(
- nni_tcp_conn *c, const SOCKADDR_STORAGE *loc, const SOCKADDR_STORAGE *rem)
-{
- memcpy(&c->sockname, loc, sizeof(*loc));
- memcpy(&c->peername, rem, sizeof(*rem));
-}
-
-void
nni_tcp_conn_close(nni_tcp_conn *c)
{
nni_mtx_lock(&c->mtx);
@@ -361,6 +352,133 @@ nni_tcp_conn_set_keepalive(nni_tcp_conn *c, bool val)
return (0);
}
+static int
+tcp_conn_get_peername(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ nng_sockaddr sa;
+
+ if (nni_win_sockaddr2nn(&sa, &c->peername) < 0) {
+ return (NNG_EADDRINVAL);
+ }
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
+}
+
+static int
+tcp_conn_get_sockname(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ nng_sockaddr sa;
+
+ if (nni_win_sockaddr2nn(&sa, &c->sockname) < 0) {
+ return (NNG_EADDRINVAL);
+ }
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
+}
+
+static int
+tcp_conn_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ bool val;
+ BOOL b;
+ int rv;
+ if ((rv = nni_copyin_bool(&val, buf, sz, t)) != 0) {
+ return (rv);
+ }
+ b = val ? TRUE : FALSE;
+ if (setsockopt(
+ c->s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b)) != 0) {
+ return (nni_win_error(WSAGetLastError()));
+ }
+ return (0);
+}
+
+static int
+tcp_conn_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ bool val;
+ BOOL b;
+ int rv;
+
+ if ((rv = nni_copyin_bool(&val, buf, sz, t)) != 0) {
+ return (rv);
+ }
+ b = val ? TRUE : FALSE;
+ if (setsockopt(
+ c->s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b)) != 0) {
+ return (nni_win_error(WSAGetLastError()));
+ }
+ return (0);
+}
+
+static int
+tcp_conn_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ BOOL b = 0;
+ int bsz = sizeof(b);
+
+ if ((getsockopt(c->s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, &bsz)) !=
+ 0) {
+ return (nni_win_error(WSAGetLastError()));
+ }
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_conn_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_conn *c = arg;
+ BOOL b = 0;
+ int bsz = sizeof(b);
+
+ if ((getsockopt(c->s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, &bsz)) !=
+ 0) {
+ return (nni_win_error(WSAGetLastError()));
+ }
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static const nni_option tcp_conn_options[] = {
+ {
+ .o_name = NNG_OPT_REMADDR,
+ .o_get = tcp_conn_get_peername,
+ },
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = tcp_conn_get_sockname,
+ },
+ {
+ .o_name = NNG_OPT_TCP_NODELAY,
+ .o_get = tcp_conn_get_nodelay,
+ .o_set = tcp_conn_set_nodelay,
+ },
+ {
+ .o_name = NNG_OPT_TCP_KEEPALIVE,
+ .o_get = tcp_conn_get_keepalive,
+ .o_set = tcp_conn_set_keepalive,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+int
+nni_tcp_conn_getopt(
+ nni_tcp_conn *c, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_getopt(tcp_conn_options, name, c, buf, szp, t));
+}
+
+int
+nni_tcp_conn_setopt(
+ nni_tcp_conn *c, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ return (nni_setopt(tcp_conn_options, name, c, buf, sz, t));
+}
+
void
nni_tcp_conn_fini(nni_tcp_conn *c)
{
@@ -384,5 +502,3 @@ nni_tcp_conn_fini(nni_tcp_conn *c)
nni_mtx_fini(&c->mtx);
NNI_FREE_STRUCT(c);
}
-
-#endif // NNG_PLATFORM_WINDOWS
diff --git a/src/platform/windows/win_tcpdial.c b/src/platform/windows/win_tcpdial.c
index 1225b560..64b4e800 100644
--- a/src/platform/windows/win_tcpdial.c
+++ b/src/platform/windows/win_tcpdial.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,8 +11,6 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_WINDOWS
-
#include "win_tcp.h"
#include <malloc.h>
@@ -115,6 +114,8 @@ tcp_dial_cb(nni_win_io *io, int rv, size_t cnt)
nni_tcp_conn * c = io->ptr;
nni_tcp_dialer *d = c->dialer;
nni_aio * aio = c->conn_aio;
+ BOOL ka;
+ BOOL nd;
NNI_ARG_UNUSED(cnt);
@@ -131,6 +132,8 @@ tcp_dial_cb(nni_win_io *io, int rv, size_t cnt)
if (c->conn_rv != 0) {
rv = c->conn_rv;
}
+ nd = d->nodelay ? TRUE : FALSE;
+ ka = d->keepalive ? TRUE : FALSE;
nni_mtx_unlock(&d->mtx);
if (rv != 0) {
@@ -140,49 +143,16 @@ tcp_dial_cb(nni_win_io *io, int rv, size_t cnt)
DWORD yes = 1;
(void) setsockopt(c->s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT,
(char *) &yes, sizeof(yes));
- nni_aio_set_output(aio, 0, c);
- nni_aio_finish(aio, 0, 0);
- }
-}
-int
-nni_tcp_dialer_set_src_addr(nni_tcp_dialer *d, const nni_sockaddr *sa)
-{
- SOCKADDR_STORAGE ss;
- struct sockaddr_in * sin;
- struct sockaddr_in6 *sin6;
- size_t sslen;
+ (void) setsockopt(
+ c->s, SOL_SOCKET, SO_KEEPALIVE, (char *) &ka, sizeof(ka));
- if ((sslen = nni_win_nn2sockaddr(&ss, sa)) == 0) {
- return (NNG_EADDRINVAL);
- }
- // Ensure we are either IPv4 or IPv6, and port is not set. (We
- // do not allow binding to a specific port.)
- switch (ss.ss_family) {
- case AF_INET:
- sin = (void *) &ss;
- if (sin->sin_port != 0) {
- return (NNG_EADDRINVAL);
- }
- break;
- case AF_INET6:
- sin6 = (void *) &ss;
- if (sin6->sin6_port != 0) {
- return (NNG_EADDRINVAL);
- }
- break;
- default:
- return (NNG_EADDRINVAL);
- }
- nni_mtx_lock(&d->mtx);
- if (d->closed) {
- nni_mtx_unlock(&d->mtx);
- return (NNG_ECLOSED);
+ (void) setsockopt(
+ c->s, IPPROTO_TCP, TCP_NODELAY, (char *) &nd, sizeof(nd));
+
+ nni_aio_set_output(aio, 0, c);
+ nni_aio_finish(aio, 0, 0);
}
- d->src = ss;
- d->srclen = sslen;
- nni_mtx_unlock(&d->mtx);
- return (0);
}
void
@@ -273,4 +243,153 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio)
nni_mtx_unlock(&d->mtx);
}
-#endif // NNG_PLATFORM_WINDOWS
+static int
+tcp_dialer_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_dialer *d = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (d == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&d->mtx);
+ d->nodelay = b;
+ nni_mtx_unlock(&d->mtx);
+ return (0);
+}
+
+static int
+tcp_dialer_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_dialer *d = arg;
+ nni_mtx_lock(&d->mtx);
+ b = d->nodelay;
+ nni_mtx_unlock(&d->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_dialer_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_dialer *d = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (d == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&d->mtx);
+ d->keepalive = b;
+ nni_mtx_unlock(&d->mtx);
+ return (0);
+}
+
+static int
+tcp_dialer_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_dialer *d = arg;
+ nni_mtx_lock(&d->mtx);
+ b = d->keepalive;
+ nni_mtx_unlock(&d->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_dialer_get_locaddr(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_dialer *d = arg;
+ nng_sockaddr sa;
+
+ nni_mtx_lock(&d->mtx);
+ if (nni_win_sockaddr2nn(&sa, &d->src) != 0) {
+ sa.s_family = NNG_AF_UNSPEC;
+ }
+ nni_mtx_unlock(&d->mtx);
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
+}
+
+static int
+tcp_dialer_set_locaddr(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_dialer * d = arg;
+ nng_sockaddr sa;
+ SOCKADDR_STORAGE ss;
+ struct sockaddr_in * sin;
+ struct sockaddr_in6 *sin6;
+ size_t sslen;
+ int rv;
+
+ if ((rv = nni_copyin_sockaddr(&sa, buf, sz, t)) != 0) {
+ return (rv);
+ }
+ if ((sslen = nni_win_nn2sockaddr(&ss, &sa)) == 0) {
+ return (NNG_EADDRINVAL);
+ }
+ // Ensure we are either IPv4 or IPv6, and port is not set. (We
+ // do not allow binding to a specific port.)
+ switch (ss.ss_family) {
+ case AF_INET:
+ sin = (void *) &ss;
+ if (sin->sin_port != 0) {
+ return (NNG_EADDRINVAL);
+ }
+ break;
+ case AF_INET6:
+ sin6 = (void *) &ss;
+ if (sin6->sin6_port != 0) {
+ return (NNG_EADDRINVAL);
+ }
+ break;
+ default:
+ return (NNG_EADDRINVAL);
+ }
+ if (d != NULL) {
+ nni_mtx_lock(&d->mtx);
+ if (d->closed) {
+ nni_mtx_unlock(&d->mtx);
+ return (NNG_ECLOSED);
+ }
+ d->src = ss;
+ d->srclen = sslen;
+ nni_mtx_unlock(&d->mtx);
+ }
+ return (0);
+}
+
+static const nni_option tcp_dialer_options[] = {
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = tcp_dialer_get_locaddr,
+ .o_set = tcp_dialer_set_locaddr,
+ },
+ {
+ .o_name = NNG_OPT_TCP_NODELAY,
+ .o_get = tcp_dialer_get_nodelay,
+ .o_set = tcp_dialer_set_nodelay,
+ },
+ {
+ .o_name = NNG_OPT_TCP_KEEPALIVE,
+ .o_get = tcp_dialer_get_keepalive,
+ .o_set = tcp_dialer_set_keepalive,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+int
+nni_tcp_dialer_getopt(
+ nni_tcp_dialer *d, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_getopt(tcp_dialer_options, name, d, buf, szp, t));
+}
+
+int
+nni_tcp_dialer_setopt(nni_tcp_dialer *d, const char *name, const void *buf,
+ size_t sz, nni_type t)
+{
+ return (nni_setopt(tcp_dialer_options, name, d, buf, sz, t));
+}
diff --git a/src/platform/windows/win_tcplisten.c b/src/platform/windows/win_tcplisten.c
index f0e195be..750de13b 100644
--- a/src/platform/windows/win_tcplisten.c
+++ b/src/platform/windows/win_tcplisten.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,8 +11,6 @@
#include "core/nng_impl.h"
-#ifdef NNG_PLATFORM_WINDOWS
-
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
@@ -76,6 +75,8 @@ tcp_accept_cb(nni_win_io *io, int rv, size_t cnt)
SOCKADDR * sa1;
SOCKADDR * sa2;
DWORD yes;
+ BOOL nd;
+ BOOL ka;
NNI_ARG_UNUSED(cnt);
@@ -92,6 +93,8 @@ tcp_accept_cb(nni_win_io *io, int rv, size_t cnt)
if (c->conn_rv != 0) {
rv = c->conn_rv;
}
+ nd = l->nodelay ? TRUE : FALSE;
+ ka = l->keepalive ? TRUE : FALSE;
nni_mtx_unlock(&l->mtx);
if (rv != 0) {
@@ -109,6 +112,13 @@ tcp_accept_cb(nni_win_io *io, int rv, size_t cnt)
yes = 1;
(void) setsockopt(c->s, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char *) &yes, sizeof(yes));
+
+ (void) setsockopt(
+ c->s, SOL_SOCKET, SO_KEEPALIVE, (char *) &ka, sizeof(ka));
+
+ (void) setsockopt(
+ c->s, IPPROTO_TCP, TCP_NODELAY, (char *) &nd, sizeof(nd));
+
nni_aio_set_output(aio, 0, c);
nni_aio_finish(aio, 0, 0);
}
@@ -130,6 +140,11 @@ nni_tcp_listener_init(nni_tcp_listener **lp)
return (rv);
}
+ // We assume these defaults -- not everyone will agree, but anyone
+ // can change them.
+ l->keepalive = false;
+ l->nodelay = true;
+
*lp = l;
return (0);
}
@@ -313,4 +328,105 @@ nni_tcp_listener_accept(nni_tcp_listener *l, nni_aio *aio)
nni_mtx_unlock(&l->mtx);
}
-#endif // NNG_PLATFORM_WINDOWS
+static int
+tcp_listener_get_locaddr(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ nni_tcp_listener *l = arg;
+ nng_sockaddr sa;
+ nni_mtx_lock(&l->mtx);
+ if (l->started) {
+ nni_win_sockaddr2nn(&sa, &l->ss);
+ } else {
+ sa.s_family = NNG_AF_UNSPEC;
+ }
+ nni_mtx_unlock(&l->mtx);
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
+}
+
+static int
+tcp_listener_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_listener *l = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (l == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&l->mtx);
+ l->nodelay = b;
+ nni_mtx_unlock(&l->mtx);
+ return (0);
+}
+
+static int
+tcp_listener_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_listener *l = arg;
+ nni_mtx_lock(&l->mtx);
+ b = l->nodelay;
+ nni_mtx_unlock(&l->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static int
+tcp_listener_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ nni_tcp_listener *l = arg;
+ int rv;
+ bool b;
+
+ if (((rv = nni_copyin_bool(&b, buf, sz, t)) != 0) || (l == NULL)) {
+ return (rv);
+ }
+ nni_mtx_lock(&l->mtx);
+ l->keepalive = b;
+ nni_mtx_unlock(&l->mtx);
+ return (0);
+}
+
+static int
+tcp_listener_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ bool b;
+ nni_tcp_listener *l = arg;
+ nni_mtx_lock(&l->mtx);
+ b = l->keepalive;
+ nni_mtx_unlock(&l->mtx);
+ return (nni_copyout_bool(b, buf, szp, t));
+}
+
+static const nni_option tcp_listener_options[] = {
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = tcp_listener_get_locaddr,
+ },
+ {
+ .o_name = NNG_OPT_TCP_NODELAY,
+ .o_set = tcp_listener_set_nodelay,
+ .o_get = tcp_listener_get_nodelay,
+ },
+ {
+ .o_name = NNG_OPT_TCP_KEEPALIVE,
+ .o_set = tcp_listener_set_keepalive,
+ .o_get = tcp_listener_get_keepalive,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+int
+nni_tcp_listener_getopt(
+ nni_tcp_listener *l, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_getopt(tcp_listener_options, name, l, buf, szp, t));
+}
+
+int
+nni_tcp_listener_setopt(nni_tcp_listener *l, const char *name, const void *buf,
+ size_t sz, nni_type t)
+{
+ return (nni_setopt(tcp_listener_options, name, l, buf, sz, t));
+}
diff --git a/src/supplemental/http/http_api.h b/src/supplemental/http/http_api.h
index a13348be..569e8532 100644
--- a/src/supplemental/http/http_api.h
+++ b/src/supplemental/http/http_api.h
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -12,9 +13,8 @@
#define NNG_SUPPLEMENTAL_HTTP_HTTP_API_H
#include "core/nng_impl.h"
-#include "nng/supplemental/tls/tls.h"
-
-#include "nng/supplemental/http/http.h"
+#include <nng/supplemental/http/http.h>
+#include <nng/supplemental/tls/tls.h>
// This represents the "internal" HTTP API. It should not be used
// or exposed to applications directly.
@@ -102,6 +102,10 @@ extern int nni_http_conn_init_tls(
extern void nni_http_conn_close(nni_http_conn *);
extern void nni_http_conn_fini(nni_http_conn *);
+extern int nni_http_conn_getopt(
+ nni_http_conn *, const char *, void *, size_t *, nni_type);
+extern int nni_http_conn_setopt(
+ nni_http_conn *, const char *, const void *, size_t, nni_type);
// Reading messages -- the caller must supply a preinitialized (but otherwise
// idle) message. We recommend the caller store this in the aio's user data.
@@ -161,11 +165,6 @@ extern void nni_http_read(nni_http_conn *, nni_aio *);
extern void nni_http_read_full(nni_http_conn *, nni_aio *);
extern void nni_http_write(nni_http_conn *, nni_aio *);
extern void nni_http_write_full(nni_http_conn *, nni_aio *);
-extern int nni_http_sock_addr(nni_http_conn *, nni_sockaddr *);
-extern int nni_http_peer_addr(nni_http_conn *, nni_sockaddr *);
-
-// nni_http_tls_verified returns true if the peer has been verified using TLS.
-extern bool nni_http_tls_verified(nni_http_conn *);
// nni_http_server will look for an existing server with the same
// name and port, or create one if one does not exist. The servers
diff --git a/src/supplemental/http/http_conn.c b/src/supplemental/http/http_conn.c
index 4d57281f..7c6159cd 100644
--- a/src/supplemental/http/http_conn.c
+++ b/src/supplemental/http/http_conn.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -13,11 +14,12 @@
#include <string.h>
#include "core/nng_impl.h"
-#include "nng/supplemental/tls/tls.h"
#include "supplemental/tls/tls_api.h"
#include "http_api.h"
+#include <nng/supplemental/tls/tls.h>
+
// We insist that individual headers fit in 8K.
// If you need more than that, you need something we can't do.
#define HTTP_BUFSIZE 8192
@@ -42,18 +44,20 @@ typedef void (*http_read_fn)(void *, nni_aio *);
typedef void (*http_write_fn)(void *, nni_aio *);
typedef void (*http_close_fn)(void *);
typedef void (*http_fini_fn)(void *);
-typedef bool (*http_verified_fn)(void *);
typedef int (*http_addr_fn)(void *, nni_sockaddr *);
-
-typedef struct nni_http_tran {
- http_read_fn h_read;
- http_write_fn h_write;
- http_addr_fn h_sock_addr;
- http_addr_fn h_peer_addr;
- http_verified_fn h_verified;
- http_close_fn h_close;
- http_fini_fn h_fini;
-} nni_http_tran;
+typedef int (*http_getopt_fn)(
+ void *, const char *, void *, size_t *, nni_type);
+typedef int (*http_setopt_fn)(
+ void *, const char *, const void *, size_t, nni_type);
+
+typedef struct {
+ http_read_fn h_read;
+ http_write_fn h_write;
+ http_getopt_fn h_getopt;
+ http_setopt_fn h_setopt;
+ http_close_fn h_close;
+ http_fini_fn h_fini;
+} http_tran;
#define SET_RD_FLAVOR(aio, f) \
nni_aio_set_prov_extra(aio, 0, ((void *) (intptr_t)(f)))
@@ -63,18 +67,17 @@ typedef struct nni_http_tran {
#define GET_WR_FLAVOR(aio) (int) ((intptr_t) nni_aio_get_prov_extra(aio, 0))
struct nng_http_conn {
- void * sock;
- http_read_fn rd;
- http_write_fn wr;
- http_addr_fn sock_addr;
- http_addr_fn peer_addr;
- http_verified_fn verified;
- http_close_fn close;
- http_fini_fn fini;
- void * ctx;
- bool closed;
- nni_list rdq; // high level http read requests
- nni_list wrq; // high level http write requests
+ void * sock;
+ http_read_fn rd;
+ http_write_fn wr;
+ http_setopt_fn setopt;
+ http_getopt_fn getopt;
+ http_close_fn close;
+ http_fini_fn fini;
+ void * ctx;
+ bool closed;
+ nni_list rdq; // high level http read requests
+ nni_list wrq; // high level http write requests
nni_aio *rd_uaio; // user aio for read
nni_aio *wr_uaio; // user aio for write
@@ -669,32 +672,31 @@ nni_http_write_full(nni_http_conn *conn, nni_aio *aio)
}
int
-nni_http_sock_addr(nni_http_conn *conn, nni_sockaddr *sa)
+nni_http_conn_getopt(
+ nni_http_conn *conn, const char *name, void *buf, size_t *szp, nni_type t)
{
int rv;
nni_mtx_lock(&conn->mtx);
- rv = conn->closed ? NNG_ECLOSED : conn->sock_addr(conn->sock, sa);
+ if (conn->closed) {
+ rv = NNG_ECLOSED;
+ } else {
+ rv = conn->getopt(conn->sock, name, buf, szp, t);
+ }
nni_mtx_unlock(&conn->mtx);
return (rv);
}
int
-nni_http_peer_addr(nni_http_conn *conn, nni_sockaddr *sa)
+nni_http_conn_setopt(nni_http_conn *conn, const char *name, const void *buf,
+ size_t sz, nni_type t)
{
int rv;
nni_mtx_lock(&conn->mtx);
- rv = conn->closed ? NNG_ECLOSED : conn->peer_addr(conn->sock, sa);
- nni_mtx_unlock(&conn->mtx);
- return (rv);
-}
-
-bool
-nni_http_tls_verified(nni_http_conn *conn)
-{
- bool rv;
-
- nni_mtx_lock(&conn->mtx);
- rv = conn->closed ? false : conn->verified(conn->sock);
+ if (conn->closed) {
+ rv = NNG_ECLOSED;
+ } else {
+ rv = conn->setopt(conn->sock, name, buf, sz, t);
+ }
nni_mtx_unlock(&conn->mtx);
return (rv);
}
@@ -721,7 +723,7 @@ nni_http_conn_fini(nni_http_conn *conn)
}
static int
-http_init(nni_http_conn **connp, nni_http_tran *tran, void *data)
+http_init(nni_http_conn **connp, http_tran *tran, void *data)
{
nni_http_conn *conn;
int rv;
@@ -745,35 +747,26 @@ http_init(nni_http_conn **connp, nni_http_tran *tran, void *data)
return (rv);
}
- conn->sock = data;
- conn->rd = tran->h_read;
- conn->wr = tran->h_write;
- conn->close = tran->h_close;
- conn->fini = tran->h_fini;
- conn->sock_addr = tran->h_sock_addr;
- conn->peer_addr = tran->h_peer_addr;
- conn->verified = tran->h_verified;
+ conn->sock = data;
+ conn->rd = tran->h_read;
+ conn->wr = tran->h_write;
+ conn->close = tran->h_close;
+ conn->fini = tran->h_fini;
+ conn->getopt = tran->h_getopt;
+ conn->setopt = tran->h_setopt;
*connp = conn;
return (0);
}
-static bool
-nni_http_verified_tcp(void *arg)
-{
- NNI_ARG_UNUSED(arg);
- return (false);
-}
-
-static nni_http_tran http_tcp_ops = {
- .h_read = (http_read_fn) nni_tcp_conn_recv,
- .h_write = (http_write_fn) nni_tcp_conn_send,
- .h_close = (http_close_fn) nni_tcp_conn_close,
- .h_fini = (http_fini_fn) nni_tcp_conn_fini,
- .h_sock_addr = (http_addr_fn) nni_tcp_conn_sockname,
- .h_peer_addr = (http_addr_fn) nni_tcp_conn_peername,
- .h_verified = (http_verified_fn) nni_http_verified_tcp,
+static http_tran http_tcp_ops = {
+ .h_read = (http_read_fn) nni_tcp_conn_recv,
+ .h_write = (http_write_fn) nni_tcp_conn_send,
+ .h_close = (http_close_fn) nni_tcp_conn_close,
+ .h_fini = (http_fini_fn) nni_tcp_conn_fini,
+ .h_getopt = (http_getopt_fn) nni_tcp_conn_getopt,
+ .h_setopt = (http_setopt_fn) nni_tcp_conn_setopt,
};
int
@@ -787,14 +780,13 @@ nni_http_conn_init_tcp(nni_http_conn **connp, nni_tcp_conn *tcp)
}
#ifdef NNG_SUPP_TLS
-static nni_http_tran http_tls_ops = {
- .h_read = (http_read_fn) nni_tls_recv,
- .h_write = (http_write_fn) nni_tls_send,
- .h_close = (http_close_fn) nni_tls_close,
- .h_fini = (http_fini_fn) nni_tls_fini,
- .h_sock_addr = (http_addr_fn) nni_tls_sockname,
- .h_peer_addr = (http_addr_fn) nni_tls_peername,
- .h_verified = (http_verified_fn) nni_tls_verified,
+static http_tran http_tls_ops = {
+ .h_read = (http_read_fn) nni_tls_recv,
+ .h_write = (http_write_fn) nni_tls_send,
+ .h_close = (http_close_fn) nni_tls_close,
+ .h_fini = (http_fini_fn) nni_tls_fini,
+ .h_getopt = (http_getopt_fn) nni_tls_getopt,
+ .h_setopt = (http_setopt_fn) nni_tls_setopt,
};
int
diff --git a/src/supplemental/tcp/tcp.c b/src/supplemental/tcp/tcp.c
index 2cb80d96..f880362b 100644
--- a/src/supplemental/tcp/tcp.c
+++ b/src/supplemental/tcp/tcp.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -51,27 +52,17 @@ nng_tcp_recv(nng_tcp *tcp, nng_aio *aio)
}
int
-nng_tcp_sockname(nng_tcp *tcp, nng_sockaddr *sa)
+nng_tcp_getopt(nng_tcp *tcp, const char *name, void *buf, size_t *szp)
{
- return (nni_tcp_conn_sockname((void *) tcp, sa));
+ return (nni_tcp_conn_getopt(
+ (void *) tcp, name, buf, szp, NNI_TYPE_OPAQUE));
}
int
-nng_tcp_peername(nng_tcp *tcp, nng_sockaddr *sa)
+nng_tcp_setopt(nng_tcp *tcp, const char *name, const void *buf, size_t sz)
{
- return (nni_tcp_conn_peername((void *) tcp, sa));
-}
-
-int
-nng_tcp_set_nodelay(nng_tcp *tcp, bool nodelay)
-{
- return (nni_tcp_conn_set_nodelay((void *) tcp, nodelay));
-}
-
-int
-nng_tcp_set_keepalive(nng_tcp *tcp, bool ka)
-{
- return (nni_tcp_conn_set_keepalive((void *) tcp, ka));
+ return (
+ nni_tcp_conn_setopt((void *) tcp, name, buf, sz, NNI_TYPE_OPAQUE));
}
int
@@ -101,12 +92,6 @@ nng_tcp_dialer_free(nng_tcp_dialer *d)
nni_tcp_dialer_fini((void *) d);
}
-int
-nng_tcp_dialer_set_source(nng_tcp_dialer *d, const nng_sockaddr *sa)
-{
- return (nni_tcp_dialer_set_src_addr((void *) d, sa));
-}
-
void
nng_tcp_dialer_dial(nng_tcp_dialer *d, const nng_sockaddr *sa, nng_aio *aio)
{
@@ -151,3 +136,19 @@ nng_tcp_listener_accept(nng_tcp_listener *l, nng_aio *aio)
{
nni_tcp_listener_accept((void *) l, aio);
}
+
+int
+nng_tcp_listener_getopt(
+ nng_tcp_listener *l, const char *name, void *buf, size_t *szp)
+{
+ return (nni_tcp_listener_getopt(
+ (void *) l, name, buf, szp, NNI_TYPE_OPAQUE));
+}
+
+int
+nng_tcp_listener_setopt(
+ nng_tcp_listener *l, const char *name, const void *buf, size_t sz)
+{
+ return (nni_tcp_listener_setopt(
+ (void *) l, name, buf, sz, NNI_TYPE_OPAQUE));
+} \ No newline at end of file
diff --git a/src/supplemental/tls/mbedtls/tls.c b/src/supplemental/tls/mbedtls/tls.c
index c01ff2ed..29f1873e 100644
--- a/src/supplemental/tls/mbedtls/tls.c
+++ b/src/supplemental/tls/mbedtls/tls.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -27,10 +28,10 @@
#include "mbedtls/ssl.h"
#include "core/nng_impl.h"
-
-#include "nng/supplemental/tls/tls.h"
#include "supplemental/tls/tls_api.h"
+#include <nng/supplemental/tls/tls.h>
+
// Implementation note. This implementation buffers data between the TLS
// encryption layer (mbedTLS) and the underlying TCP socket. As a result,
// there may be some additional latency caused by buffer draining and
@@ -310,11 +311,13 @@ nni_tls_init(nni_tls **tpp, nng_tls_config *cfg, nni_tcp_conn *tcp)
{
nni_tls *tp;
int rv;
+ bool on = true;
// During the handshake, disable Nagle to shorten the
// negotiation. Once things are set up the caller can
// re-enable Nagle if so desired.
- (void) nni_tcp_conn_set_nodelay(tcp, true);
+ (void) nni_tcp_conn_setopt(
+ tcp, NNG_OPT_TCP_NODELAY, &on, sizeof(on), NNI_TYPE_BOOL);
if ((tp = NNI_ALLOC_STRUCT(tp)) == NULL) {
return (NNG_ENOMEM);
@@ -612,28 +615,49 @@ nni_tls_recv(nni_tls *tp, nni_aio *aio)
nni_mtx_unlock(&tp->lk);
}
-int
-nni_tls_peername(nni_tls *tp, nni_sockaddr *sa)
+static int
+tls_get_verified(void *arg, void *buf, size_t *szp, nni_type t)
{
- return (nni_tcp_conn_peername(tp->tcp, sa));
-}
+ nni_tls *tp = arg;
+ bool v = (mbedtls_ssl_get_verify_result(&tp->ctx) == 0);
-int
-nni_tls_sockname(nni_tls *tp, nni_sockaddr *sa)
-{
- return (nni_tcp_conn_sockname(tp->tcp, sa));
+ return (nni_copyout_bool(v, buf, szp, t));
}
+static const nni_option tls_options[] = {
+ {
+ .o_name = NNG_OPT_TLS_VERIFIED,
+ .o_get = tls_get_verified,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
int
-nni_tls_set_nodelay(nni_tls *tp, bool val)
+nni_tls_setopt(
+ nni_tls *tp, const char *name, const void *buf, size_t sz, nni_type t)
{
- return (nni_tcp_conn_set_nodelay(tp->tcp, val));
+ int rv;
+
+ if ((rv = nni_tcp_conn_setopt(tp->tcp, name, buf, sz, t)) !=
+ NNG_ENOTSUP) {
+ return (rv);
+ }
+ return (nni_setopt(tls_options, name, tp, buf, sz, t));
}
int
-nni_tls_set_keepalive(nni_tls *tp, bool val)
+nni_tls_getopt(
+ nni_tls *tp, const char *name, void *buf, size_t *szp, nni_type t)
{
- return (nni_tcp_conn_set_keepalive(tp->tcp, val));
+ int rv;
+
+ if ((rv = nni_tcp_conn_getopt(tp->tcp, name, buf, szp, t)) !=
+ NNG_ENOTSUP) {
+ return (rv);
+ }
+ return (nni_getopt(tls_options, name, tp, buf, szp, t));
}
static void
@@ -790,18 +814,6 @@ nni_tls_close(nni_tls *tp)
nni_mtx_unlock(&tp->lk);
}
-const char *
-nni_tls_ciphersuite_name(nni_tls *tp)
-{
- return (mbedtls_ssl_get_ciphersuite(&tp->ctx));
-}
-
-bool
-nni_tls_verified(nni_tls *tp)
-{
- return (mbedtls_ssl_get_verify_result(&tp->ctx) == 0);
-}
-
int
nng_tls_config_server_name(nng_tls_config *cfg, const char *name)
{
diff --git a/src/supplemental/tls/none/tls.c b/src/supplemental/tls/none/tls.c
index e9d84e19..257bb6b1 100644
--- a/src/supplemental/tls/none/tls.c
+++ b/src/supplemental/tls/none/tls.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -17,9 +18,10 @@
// We provide stub functions only to satisfy linkage.
#include "core/nng_impl.h"
-#include "nng/supplemental/tls/tls.h"
#include "supplemental/tls/tls_api.h"
+#include <nng/supplemental/tls/tls.h>
+
void
nni_tls_config_fini(nng_tls_config *cfg)
{
@@ -72,40 +74,34 @@ nni_tls_recv(nni_tls *tp, nni_aio *aio)
nni_aio_finish_error(aio, NNG_ENOTSUP);
}
-int
-nni_tls_peername(nni_tls *tp, nni_sockaddr *sa)
-{
- NNI_ARG_UNUSED(tp);
- NNI_ARG_UNUSED(sa);
- return (NNG_ENOTSUP);
-}
-
-int
-nni_tls_sockname(nni_tls *tp, nni_sockaddr *sa)
-{
- NNI_ARG_UNUSED(tp);
- NNI_ARG_UNUSED(sa);
- return (NNG_ENOTSUP);
-}
-
void
nni_tls_close(nni_tls *tp)
{
NNI_ARG_UNUSED(tp);
}
-const char *
-nni_tls_ciphersuite_name(nni_tls *tp)
+int
+nni_tls_getopt(
+ nni_tls *tp, const char *name, void *buf, size_t *szp, nni_type t)
{
NNI_ARG_UNUSED(tp);
- return (NULL);
+ NNI_ARG_UNUSED(name);
+ NNI_ARG_UNUSED(buf);
+ NNI_ARG_UNUSED(szp);
+ NNI_ARG_UNUSED(t);
+ return (NNG_ENOTSUP);
}
-bool
-nni_tls_verified(nni_tls *tp)
+int
+nni_tls_setopt(
+ nni_tls *tp, const char *name, const void *buf, size_t sz, nni_type t)
{
NNI_ARG_UNUSED(tp);
- return (false);
+ NNI_ARG_UNUSED(name);
+ NNI_ARG_UNUSED(buf);
+ NNI_ARG_UNUSED(sz);
+ NNI_ARG_UNUSED(t);
+ return (NNG_ENOTSUP);
}
int
diff --git a/src/supplemental/tls/tls_api.h b/src/supplemental/tls/tls_api.h
index 53dba7fe..63424d5e 100644
--- a/src/supplemental/tls/tls_api.h
+++ b/src/supplemental/tls/tls_api.h
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -13,6 +14,8 @@
#include <stdbool.h>
+#include <nng/supplemental/tls/tls.h>
+
// nni_tls represents the context for a single TLS stream.
typedef struct nni_tls nni_tls;
@@ -36,19 +39,10 @@ extern void nni_tls_close(nni_tls *);
extern void nni_tls_fini(nni_tls *);
extern void nni_tls_send(nni_tls *, nng_aio *);
extern void nni_tls_recv(nni_tls *, nng_aio *);
-extern int nni_tls_sockname(nni_tls *, nni_sockaddr *);
-extern int nni_tls_peername(nni_tls *, nni_sockaddr *);
-extern int nni_tls_set_nodelay(nni_tls *, bool);
-extern int nni_tls_set_keepalive(nni_tls *, bool);
-
-// nni_tls_verified returns true if the peer, or false if the peer did not
-// verify. (During the handshake phase, the peer is not verified, so this
-// might return false if executed too soon. The verification status will
-// be accurate once the handshake is finished, however.
-extern bool nni_tls_verified(nni_tls *);
-
-// nni_tls_ciphersuite_name returns the name of the ciphersuite in use.
-extern const char *nni_tls_ciphersuite_name(nni_tls *);
+
+extern int nni_tls_setopt(
+ nni_tls *, const char *, const void *, size_t, nni_type);
+extern int nni_tls_getopt(nni_tls *, const char *, void *, size_t *, nni_type);
// TBD: getting additional peer certificate information...
diff --git a/src/supplemental/websocket/websocket.c b/src/supplemental/websocket/websocket.c
index c214e6d7..3d3a68cb 100644
--- a/src/supplemental/websocket/websocket.c
+++ b/src/supplemental/websocket/websocket.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -698,22 +699,45 @@ ws_send_control(nni_ws *ws, uint8_t op, uint8_t *buf, size_t len)
ws_start_write(ws);
}
+static const nni_option ws_options[] = {
+ {
+ .o_name = NULL,
+ },
+};
+
int
-nni_ws_sock_addr(nni_ws *ws, nni_sockaddr *sa)
+nni_ws_getopt(nni_ws *ws, const char *name, void *buf, size_t *szp, nni_type t)
{
int rv;
+
nni_mtx_lock(&ws->mtx);
- rv = ws->closed ? NNG_ECLOSED : nni_http_sock_addr(ws->http, sa);
+ if (ws->closed) {
+ nni_mtx_unlock(&ws->mtx);
+ return (NNG_ECLOSED);
+ }
+ rv = nni_http_conn_getopt(ws->http, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(ws_options, name, ws, buf, szp, t);
+ }
nni_mtx_unlock(&ws->mtx);
return (rv);
}
int
-nni_ws_peer_addr(nni_ws *ws, nni_sockaddr *sa)
+nni_ws_setopt(
+ nni_ws *ws, const char *name, const void *buf, size_t sz, nni_type t)
{
int rv;
+
nni_mtx_lock(&ws->mtx);
- rv = ws->closed ? NNG_ECLOSED : nni_http_peer_addr(ws->http, sa);
+ if (ws->closed) {
+ nni_mtx_unlock(&ws->mtx);
+ return (NNG_ECLOSED);
+ }
+ rv = nni_http_conn_setopt(ws->http, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(ws_options, name, ws, buf, sz, t);
+ }
nni_mtx_unlock(&ws->mtx);
return (rv);
}
@@ -1098,18 +1122,6 @@ nni_ws_close(nni_ws *ws)
nni_ws_close_error(ws, WS_CLOSE_NORMAL_CLOSE);
}
-nni_http_res *
-nni_ws_response(nni_ws *ws)
-{
- return (ws->res);
-}
-
-nni_http_req *
-nni_ws_request(nni_ws *ws)
-{
- return (ws->req);
-}
-
const char *
nni_ws_request_headers(nni_ws *ws)
{
@@ -1132,17 +1144,6 @@ nni_ws_response_headers(nni_ws *ws)
return (ws->reshdrs);
}
-bool
-nni_ws_tls_verified(nni_ws *ws)
-{
- bool rv;
-
- nni_mtx_lock(&ws->mtx);
- rv = nni_http_tls_verified(ws->http);
- nni_mtx_unlock(&ws->mtx);
- return (rv);
-}
-
static void
ws_fini(void *arg)
{
diff --git a/src/supplemental/websocket/websocket.h b/src/supplemental/websocket/websocket.h
index 9936b10f..88b4bfb4 100644
--- a/src/supplemental/websocket/websocket.h
+++ b/src/supplemental/websocket/websocket.h
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -52,18 +53,16 @@ extern int nni_ws_dialer_get_tls(nni_ws_dialer *, nng_tls_config **);
// not confirm the server's response at the HTTP level. (It can still issue
// a websocket close).
-extern void nni_ws_send_msg(nni_ws *, nng_aio *);
-extern void nni_ws_recv_msg(nni_ws *, nng_aio *);
-extern nng_http_res *nni_ws_response(nni_ws *);
-extern nng_http_req *nni_ws_request(nni_ws *);
-extern int nni_ws_sock_addr(nni_ws *, nni_sockaddr *);
-extern int nni_ws_peer_addr(nni_ws *, nni_sockaddr *);
-extern void nni_ws_close(nni_ws *);
-extern void nni_ws_close_error(nni_ws *, uint16_t);
-extern void nni_ws_fini(nni_ws *);
-extern const char * nni_ws_response_headers(nni_ws *);
-extern const char * nni_ws_request_headers(nni_ws *);
-extern bool nni_ws_tls_verified(nni_ws *);
+extern void nni_ws_send_msg(nni_ws *, nng_aio *);
+extern void nni_ws_recv_msg(nni_ws *, nng_aio *);
+extern void nni_ws_close(nni_ws *);
+extern void nni_ws_close_error(nni_ws *, uint16_t);
+extern void nni_ws_fini(nni_ws *);
+extern const char *nni_ws_response_headers(nni_ws *);
+extern const char *nni_ws_request_headers(nni_ws *);
+extern int nni_ws_getopt(nni_ws *, const char *, void *, size_t *, nni_type);
+extern int nni_ws_setopt(
+ nni_ws *, const char *, const void *, size_t, nni_type);
// The implementation will send periodic PINGs, and respond with PONGs.
diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c
index 4f7dbd72..38b8cbaf 100644
--- a/src/transport/tcp/tcp.c
+++ b/src/transport/tcp/tcp.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -353,8 +354,10 @@ tcptran_pipe_nego_cb(void *arg)
NNI_GET16(&p->rxlen[4], p->peer);
p->useraio = NULL;
- (void) nni_tcp_conn_set_nodelay(p->conn, p->nodelay);
- (void) nni_tcp_conn_set_keepalive(p->conn, p->keepalive);
+ (void) nni_tcp_conn_setopt(p->conn, NNG_OPT_TCP_NODELAY, &p->nodelay,
+ sizeof(p->nodelay), NNI_TYPE_BOOL);
+ (void) nni_tcp_conn_setopt(p->conn, NNG_OPT_TCP_KEEPALIVE,
+ &p->keepalive, sizeof(p->keepalive), NNI_TYPE_BOOL);
nni_mtx_unlock(&ep->mtx);
@@ -671,45 +674,11 @@ tcptran_pipe_peer(void *arg)
}
static int
-tcptran_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_pipe_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
{
tcptran_pipe *p = arg;
- int rv;
- nni_sockaddr sa;
-
- memset(&sa, 0, sizeof(sa));
- if ((rv = nni_tcp_conn_sockname(p->conn, &sa)) == 0) {
- rv = nni_copyout_sockaddr(&sa, v, szp, t);
- }
- return (rv);
-}
-
-static int
-tcptran_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tcptran_pipe *p = arg;
- int rv;
- nni_sockaddr sa;
-
- memset(&sa, 0, sizeof(sa));
- if ((rv = nni_tcp_conn_peername(p->conn, &sa)) == 0) {
- rv = nni_copyout_sockaddr(&sa, v, szp, t);
- }
- return (rv);
-}
-
-static int
-tcptran_pipe_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tcptran_pipe *p = arg;
- return (nni_copyout_bool(p->keepalive, v, szp, t));
-}
-
-static int
-tcptran_pipe_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tcptran_pipe *p = arg;
- return (nni_copyout_bool(p->nodelay, v, szp, t));
+ return (nni_tcp_conn_getopt(p->conn, name, buf, szp, t));
}
static void
@@ -761,7 +730,7 @@ tcptran_ep_close(void *arg)
}
static int
-tcptran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
+tcptran_dialer_init(void **dp, nni_url *url, nni_dialer *ndialer)
{
tcptran_ep * ep;
int rv;
@@ -844,7 +813,8 @@ tcptran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
return (rv);
}
if ((srcsa.s_family != NNG_AF_UNSPEC) &&
- ((rv = nni_tcp_dialer_set_src_addr(ep->dialer, &srcsa)) != 0)) {
+ ((rv = nni_tcp_dialer_setopt(ep->dialer, NNG_OPT_LOCADDR, &srcsa,
+ sizeof(srcsa), NNI_TYPE_SOCKADDR)) != 0)) {
tcptran_ep_fini(ep);
return (rv);
}
@@ -852,7 +822,7 @@ tcptran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
return (0);
}
static int
-tcptran_ep_init_listener(void **lp, nni_url *url, nni_listener *nlistener)
+tcptran_listener_init(void **lp, nni_url *url, nni_listener *nlistener)
{
tcptran_ep *ep;
int rv;
@@ -967,10 +937,19 @@ tcptran_ep_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
tcptran_ep *ep = arg;
if (ep->listener != NULL) {
- char ustr[128];
- char ipstr[48]; // max for IPv6 addresses including []
- char portstr[6]; // max for 16-bit port
- nni_ntop(&ep->bsa, ipstr, portstr);
+ char ustr[128];
+ char ipstr[48]; // max for IPv6 addresses including []
+ char portstr[6]; // max for 16-bit port
+ nng_sockaddr sa;
+ size_t sz = sizeof(sa);
+ int rv;
+ rv = nni_tcp_listener_getopt(ep->listener, NNG_OPT_LOCADDR,
+ &sa, &sz, NNI_TYPE_SOCKADDR);
+ if (rv != 0) {
+ return (rv);
+ }
+
+ nni_ntop(&sa, ipstr, portstr);
snprintf(ustr, sizeof(ustr), "tcp://%s:%s", ipstr, portstr);
return (nni_copyout_str(ustr, v, szp, t));
}
@@ -1115,41 +1094,18 @@ tcptran_ep_get_locaddr(void *arg, void *buf, size_t *szp, nni_opt_type t)
return (rv);
}
-static nni_option tcptran_pipe_options[] = {
- {
- .o_name = NNG_OPT_LOCADDR,
- .o_get = tcptran_pipe_get_locaddr,
- },
- {
- .o_name = NNG_OPT_REMADDR,
- .o_get = tcptran_pipe_get_remaddr,
- },
- {
- .o_name = NNG_OPT_TCP_KEEPALIVE,
- .o_get = tcptran_pipe_get_keepalive,
- },
- {
- .o_name = NNG_OPT_TCP_NODELAY,
- .o_get = tcptran_pipe_get_nodelay,
- },
- // terminate list
- {
- .o_name = NULL,
- },
-};
-
static nni_tran_pipe_ops tcptran_pipe_ops = {
- .p_init = tcptran_pipe_init,
- .p_fini = tcptran_pipe_fini,
- .p_stop = tcptran_pipe_stop,
- .p_send = tcptran_pipe_send,
- .p_recv = tcptran_pipe_recv,
- .p_close = tcptran_pipe_close,
- .p_peer = tcptran_pipe_peer,
- .p_options = tcptran_pipe_options,
+ .p_init = tcptran_pipe_init,
+ .p_fini = tcptran_pipe_fini,
+ .p_stop = tcptran_pipe_stop,
+ .p_send = tcptran_pipe_send,
+ .p_recv = tcptran_pipe_recv,
+ .p_close = tcptran_pipe_close,
+ .p_peer = tcptran_pipe_peer,
+ .p_getopt = tcptran_pipe_getopt,
};
-static nni_option tcptran_dialer_options[] = {
+static const nni_option tcptran_ep_opts[] = {
{
.o_name = NNG_OPT_RECVMAXSZ,
.o_get = tcptran_ep_get_recvmaxsz,
@@ -1159,67 +1115,87 @@ static nni_option tcptran_dialer_options[] = {
.o_name = NNG_OPT_URL,
.o_get = tcptran_ep_get_url,
},
- {
- .o_name = NNG_OPT_TCP_NODELAY,
- .o_get = tcptran_ep_get_nodelay,
- .o_set = tcptran_ep_set_nodelay,
- },
- {
- .o_name = NNG_OPT_TCP_KEEPALIVE,
- .o_get = tcptran_ep_get_keepalive,
- .o_set = tcptran_ep_set_keepalive,
- },
// terminate list
{
.o_name = NULL,
},
};
-static nni_option tcptran_listener_options[] = {
- {
- .o_name = NNG_OPT_RECVMAXSZ,
- .o_get = tcptran_ep_get_recvmaxsz,
- .o_set = tcptran_ep_set_recvmaxsz,
- },
- {
- .o_name = NNG_OPT_LOCADDR,
- .o_get = tcptran_ep_get_locaddr,
- },
- {
- .o_name = NNG_OPT_URL,
- .o_get = tcptran_ep_get_url,
- },
- {
- .o_name = NNG_OPT_TCP_NODELAY,
- .o_get = tcptran_ep_get_nodelay,
- .o_set = tcptran_ep_set_nodelay,
- },
- {
- .o_name = NNG_OPT_TCP_KEEPALIVE,
- .o_get = tcptran_ep_get_keepalive,
- .o_set = tcptran_ep_set_keepalive,
- },
- // terminate list
- {
- .o_name = NULL,
- },
-};
+static int
+tcptran_dialer_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ tcptran_ep *ep = arg;
+ int rv;
+
+ rv = nni_tcp_dialer_getopt(ep->dialer, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(tcptran_ep_opts, name, ep, buf, szp, t);
+ }
+ return (rv);
+}
+
+static int
+tcptran_dialer_setopt(
+ void *arg, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ tcptran_ep *ep = arg;
+ int rv;
+
+ rv = nni_tcp_dialer_setopt(
+ ep != NULL ? ep->dialer : NULL, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(tcptran_ep_opts, name, ep, buf, sz, t);
+ }
+ return (rv);
+}
+
+static int
+tcptran_listener_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ tcptran_ep *ep = arg;
+ int rv;
+
+ rv = nni_tcp_listener_getopt(ep->listener, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(tcptran_ep_opts, name, ep, buf, szp, t);
+ }
+ return (rv);
+}
+
+static int
+tcptran_listener_setopt(
+ void *arg, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ tcptran_ep *ep = arg;
+ int rv;
+
+ rv = nni_tcp_listener_setopt(
+ ep != NULL ? ep->listener : NULL, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(tcptran_ep_opts, name, ep, buf, sz, t);
+ }
+ return (rv);
+}
static nni_tran_dialer_ops tcptran_dialer_ops = {
- .d_init = tcptran_ep_init_dialer,
+ .d_init = tcptran_dialer_init,
.d_fini = tcptran_ep_fini,
.d_connect = tcptran_ep_connect,
.d_close = tcptran_ep_close,
- .d_options = tcptran_dialer_options,
+ .d_getopt = tcptran_dialer_getopt,
+ .d_setopt = tcptran_dialer_setopt,
};
static nni_tran_listener_ops tcptran_listener_ops = {
- .l_init = tcptran_ep_init_listener,
- .l_fini = tcptran_ep_fini,
- .l_bind = tcptran_ep_bind,
- .l_accept = tcptran_ep_accept,
- .l_close = tcptran_ep_close,
- .l_options = tcptran_listener_options,
+ .l_init = tcptran_listener_init,
+ .l_fini = tcptran_ep_fini,
+ .l_bind = tcptran_ep_bind,
+ .l_accept = tcptran_ep_accept,
+ .l_close = tcptran_ep_close,
+ .l_getopt = tcptran_listener_getopt,
+ .l_setopt = tcptran_listener_setopt,
};
static nni_tran tcp_tran = {
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index 35356054..dc198ebf 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -366,8 +367,12 @@ tlstran_pipe_nego_cb(void *arg)
NNI_GET16(&p->rxlen[4], p->peer);
p->useraio = NULL;
nni_mtx_unlock(&ep->mtx);
- (void) nni_tls_set_nodelay(p->tls, p->nodelay);
- (void) nni_tls_set_keepalive(p->tls, p->keepalive);
+
+ (void) nni_tls_setopt(p->tls, NNG_OPT_TCP_NODELAY, &p->nodelay,
+ sizeof(p->nodelay), NNI_TYPE_BOOL);
+ (void) nni_tls_setopt(p->tls, NNG_OPT_TCP_KEEPALIVE, &p->keepalive,
+ sizeof(p->keepalive), NNI_TYPE_BOOL);
+
nni_aio_set_output(uaio, 0, p);
nni_aio_finish(uaio, 0, 0);
return;
@@ -660,48 +665,6 @@ tlstran_pipe_peer(void *arg)
return (p->peer);
}
-static int
-tlstran_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_pipe *p = arg;
- int rv;
- nni_sockaddr sa;
-
- memset(&sa, 0, sizeof(sa));
- if ((rv = nni_tls_sockname(p->tls, &sa)) == 0) {
- rv = nni_copyout_sockaddr(&sa, v, szp, t);
- }
- return (rv);
-}
-
-static int
-tlstran_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_pipe *p = arg;
- int rv;
- nni_sockaddr sa;
-
- memset(&sa, 0, sizeof(sa));
- if ((rv = nni_tls_peername(p->tls, &sa)) == 0) {
- rv = nni_copyout_sockaddr(&sa, v, szp, t);
- }
- return (rv);
-}
-
-static int
-tlstran_pipe_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_pipe *p = arg;
- return (nni_copyout_bool(p->keepalive, v, szp, t));
-}
-
-static int
-tlstran_pipe_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_pipe *p = arg;
- return (nni_copyout_bool(p->nodelay, v, szp, t));
-}
-
static void
tlstran_ep_fini(void *arg)
{
@@ -1215,50 +1178,35 @@ tlstran_ep_set_cert_key_file(
return (rv);
}
-static int
-tlstran_pipe_get_verified(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_pipe *p = arg;
-
- return (nni_copyout_bool(nni_tls_verified(p->tls), v, szp, t));
-}
-
-static nni_option tlstran_pipe_options[] = {
- {
- .o_name = NNG_OPT_LOCADDR,
- .o_get = tlstran_pipe_get_locaddr,
- },
- {
- .o_name = NNG_OPT_REMADDR,
- .o_get = tlstran_pipe_get_remaddr,
- },
- {
- .o_name = NNG_OPT_TLS_VERIFIED,
- .o_get = tlstran_pipe_get_verified,
- },
- {
- .o_name = NNG_OPT_TCP_KEEPALIVE,
- .o_get = tlstran_pipe_get_keepalive,
- },
- {
- .o_name = NNG_OPT_TCP_NODELAY,
- .o_get = tlstran_pipe_get_nodelay,
- },
+static const nni_option tlstran_pipe_opts[] = {
// terminate list
{
.o_name = NULL,
},
};
+static int
+tlstran_pipe_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ tlstran_pipe *p = arg;
+ int rv;
+
+ if ((rv = nni_tls_getopt(p->tls, name, buf, szp, t)) == NNG_ENOTSUP) {
+ rv = nni_getopt(tlstran_pipe_opts, name, p, buf, szp, t);
+ }
+ return (rv);
+}
+
static nni_tran_pipe_ops tlstran_pipe_ops = {
- .p_init = tlstran_pipe_init,
- .p_fini = tlstran_pipe_fini,
- .p_stop = tlstran_pipe_stop,
- .p_send = tlstran_pipe_send,
- .p_recv = tlstran_pipe_recv,
- .p_close = tlstran_pipe_close,
- .p_peer = tlstran_pipe_peer,
- .p_options = tlstran_pipe_options,
+ .p_init = tlstran_pipe_init,
+ .p_fini = tlstran_pipe_fini,
+ .p_stop = tlstran_pipe_stop,
+ .p_send = tlstran_pipe_send,
+ .p_recv = tlstran_pipe_recv,
+ .p_close = tlstran_pipe_close,
+ .p_peer = tlstran_pipe_peer,
+ .p_getopt = tlstran_pipe_getopt,
};
static nni_option tlstran_dialer_options[] = {
diff --git a/src/transport/ws/websocket.c b/src/transport/ws/websocket.c
index 1d5358f6..bf10f7e0 100644
--- a/src/transport/ws/websocket.c
+++ b/src/transport/ws/websocket.c
@@ -1,6 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2018 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -14,12 +15,12 @@
#include <string.h>
#include "core/nng_impl.h"
-#include "nng/supplemental/tls/tls.h"
#include "supplemental/http/http_api.h"
#include "supplemental/tls/tls_api.h"
#include "supplemental/websocket/websocket.h"
-#include "nng/transport/ws/websocket.h"
+#include <nng/supplemental/tls/tls.h>
+#include <nng/transport/ws/websocket.h>
typedef struct ws_dialer ws_dialer;
typedef struct ws_listener ws_listener;
@@ -577,34 +578,6 @@ ws_listener_set_reshdrs(void *arg, const void *v, size_t sz, nni_opt_type t)
}
static int
-ws_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_pipe * p = arg;
- int rv;
- nni_sockaddr sa;
-
- memset(&sa, 0, sizeof(sa));
- if ((rv = nni_ws_sock_addr(p->ws, &sa)) == 0) {
- rv = nni_copyout_sockaddr(&sa, v, szp, t);
- }
- return (rv);
-}
-
-static int
-ws_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_pipe * p = arg;
- int rv;
- nni_sockaddr sa;
-
- memset(&sa, 0, sizeof(sa));
- if ((rv = nni_ws_peer_addr(p->ws, &sa)) == 0) {
- rv = nni_copyout_sockaddr(&sa, v, szp, t);
- }
- return (rv);
-}
-
-static int
ws_pipe_get_reshdrs(void *arg, void *v, size_t *szp, nni_opt_type t)
{
ws_pipe * p = arg;
@@ -628,23 +601,7 @@ ws_pipe_get_reqhdrs(void *arg, void *v, size_t *szp, nni_opt_type t)
return (nni_copyout_str(s, v, szp, t));
}
-static int
-ws_pipe_get_tls_verified(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_pipe *p = arg;
- return (nni_copyout_bool(nni_ws_tls_verified(p->ws), v, szp, t));
-}
-
-static nni_option ws_pipe_options[] = {
-
- {
- .o_name = NNG_OPT_LOCADDR,
- .o_get = ws_pipe_get_locaddr,
- },
- {
- .o_name = NNG_OPT_REMADDR,
- .o_get = ws_pipe_get_remaddr,
- },
+static const nni_option ws_pipe_options[] = {
{
.o_name = NNG_OPT_WS_REQUEST_HEADERS,
.o_get = ws_pipe_get_reqhdrs,
@@ -653,25 +610,33 @@ static nni_option ws_pipe_options[] = {
.o_name = NNG_OPT_WS_RESPONSE_HEADERS,
.o_get = ws_pipe_get_reshdrs,
},
- {
- .o_name = NNG_OPT_TLS_VERIFIED,
- .o_get = ws_pipe_get_tls_verified,
- },
// terminate list
{
.o_name = NULL,
}
};
+static int
+ws_pipe_getopt(void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ ws_pipe *p = arg;
+ int rv;
+
+ if ((rv = nni_ws_getopt(p->ws, name, buf, szp, t)) == NNG_ENOTSUP) {
+ rv = nni_getopt(ws_pipe_options, name, p, buf, szp, t);
+ }
+ return (rv);
+}
+
static nni_tran_pipe_ops ws_pipe_ops = {
- .p_init = ws_pipe_init,
- .p_fini = ws_pipe_fini,
- .p_stop = ws_pipe_stop,
- .p_send = ws_pipe_send,
- .p_recv = ws_pipe_recv,
- .p_close = ws_pipe_close,
- .p_peer = ws_pipe_peer,
- .p_options = ws_pipe_options,
+ .p_init = ws_pipe_init,
+ .p_fini = ws_pipe_fini,
+ .p_stop = ws_pipe_stop,
+ .p_send = ws_pipe_send,
+ .p_recv = ws_pipe_recv,
+ .p_close = ws_pipe_close,
+ .p_peer = ws_pipe_peer,
+ .p_getopt = ws_pipe_getopt,
};
static nni_option ws_dialer_options[] = {