aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/platform/posix/posix_ipc.h10
-rw-r--r--src/platform/posix/posix_ipcconn.c32
-rw-r--r--src/platform/posix/posix_ipcdial.c48
-rw-r--r--src/platform/posix/posix_ipclisten.c12
-rw-r--r--src/platform/posix/posix_pollq_epoll.c37
-rw-r--r--src/platform/posix/posix_pollq_kqueue.c34
-rw-r--r--src/platform/posix/posix_pollq_port.c23
-rw-r--r--src/platform/posix/posix_resolv_gai.c16
-rw-r--r--src/platform/posix/posix_tcp.h18
-rw-r--r--src/platform/posix/posix_tcpconn.c28
-rw-r--r--src/platform/posix/posix_tcpdial.c54
-rw-r--r--src/platform/posix/posix_tcplisten.c11
-rw-r--r--src/supplemental/tcp/tcp.c7
-rw-r--r--src/supplemental/tls/mbedtls/tls.c58
14 files changed, 211 insertions, 177 deletions
diff --git a/src/platform/posix/posix_ipc.h b/src/platform/posix/posix_ipc.h
index f0b9b5ef..894a5e96 100644
--- a/src/platform/posix/posix_ipc.h
+++ b/src/platform/posix/posix_ipc.h
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -29,6 +29,7 @@ struct nni_ipc_conn {
nni_mtx mtx;
nni_aio * dial_aio;
nni_ipc_dialer *dialer;
+ nni_reap_item reap;
};
struct nni_ipc_dialer {
@@ -37,11 +38,12 @@ struct nni_ipc_dialer {
bool closed;
nni_mtx mtx;
nng_sockaddr sa;
- int refcnt;
- bool fini;
+ nni_atomic_u64 ref;
+ nni_atomic_bool fini;
};
-extern int nni_posix_ipc_init(nni_ipc_conn **, nni_posix_pfd *);
+extern int nni_posix_ipc_alloc(nni_ipc_conn **, nni_ipc_dialer *);
+extern void nni_posix_ipc_init(nni_ipc_conn *, nni_posix_pfd *);
extern void nni_posix_ipc_start(nni_ipc_conn *);
extern void nni_posix_ipc_dialer_rele(nni_ipc_dialer *);
diff --git a/src/platform/posix/posix_ipcconn.c b/src/platform/posix/posix_ipcconn.c
index 2b078aa5..e4d783f3 100644
--- a/src/platform/posix/posix_ipcconn.c
+++ b/src/platform/posix/posix_ipcconn.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -200,7 +200,9 @@ ipc_close(void *arg)
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, NNG_ECLOSED);
}
- nni_posix_pfd_close(c->pfd);
+ if (c->pfd != NULL) {
+ nni_posix_pfd_close(c->pfd);
+ }
}
nni_mtx_unlock(&c->mtx);
}
@@ -483,14 +485,13 @@ nni_posix_ipc_start(nni_ipc_conn *c)
}
static void
-ipc_free(void *arg)
+ipc_reap(void *arg)
{
ipc_conn *c = arg;
ipc_close(c);
- nni_posix_pfd_fini(c->pfd);
- nni_mtx_lock(&c->mtx); // not strictly needed, but shut up TSAN
- c->pfd = NULL;
- nni_mtx_unlock(&c->mtx);
+ if (c->pfd != NULL) {
+ nni_posix_pfd_fini(c->pfd);
+ }
nni_mtx_fini(&c->mtx);
if (c->dialer != NULL) {
@@ -500,6 +501,13 @@ ipc_free(void *arg)
NNI_FREE_STRUCT(c);
}
+static void
+ipc_free(void *arg)
+{
+ ipc_conn *c = arg;
+ nni_reap(&c->reap, ipc_reap, c);
+}
+
static const nni_option ipc_options[] = {
{
.o_name = NNG_OPT_LOCADDR,
@@ -545,7 +553,7 @@ ipc_setx(void *arg, const char *name, const void *val, size_t sz, nni_type t)
}
int
-nni_posix_ipc_init(nni_ipc_conn **cp, nni_posix_pfd *pfd)
+nni_posix_ipc_alloc(nni_ipc_conn **cp, nni_ipc_dialer *d)
{
ipc_conn *c;
@@ -554,7 +562,7 @@ nni_posix_ipc_init(nni_ipc_conn **cp, nni_posix_pfd *pfd)
}
c->closed = false;
- c->pfd = pfd;
+ c->dialer = d;
c->stream.s_free = ipc_free;
c->stream.s_close = ipc_close;
c->stream.s_send = ipc_send;
@@ -569,3 +577,9 @@ nni_posix_ipc_init(nni_ipc_conn **cp, nni_posix_pfd *pfd)
*cp = c;
return (0);
}
+
+void
+nni_posix_ipc_init(nni_ipc_conn *c, nni_posix_pfd *pfd)
+{
+ c->pfd = pfd;
+}
diff --git a/src/platform/posix/posix_ipcdial.c b/src/platform/posix/posix_ipcdial.c
index 50c7a897..65061767 100644
--- a/src/platform/posix/posix_ipcdial.c
+++ b/src/platform/posix/posix_ipcdial.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -62,26 +62,17 @@ ipc_dialer_free(void *arg)
ipc_dialer *d = arg;
ipc_dialer_close(d);
- nni_mtx_lock(&d->mtx);
- d->fini = true;
- if (d->refcnt) {
- nni_mtx_unlock(&d->mtx);
- return;
- }
- nni_mtx_unlock(&d->mtx);
- ipc_dialer_fini(d);
+ nni_atomic_set_bool(&d->fini, true);
+ nni_posix_ipc_dialer_rele(d);
}
void
nni_posix_ipc_dialer_rele(ipc_dialer *d)
{
- nni_mtx_lock(&d->mtx);
- d->refcnt--;
- if ((d->refcnt > 0) || (!d->fini)) {
- nni_mtx_unlock(&d->mtx);
+ if (((nni_atomic_dec64_nv(&d->ref)) != 0) ||
+ (!nni_atomic_get_bool(&d->fini))) {
return;
}
- nni_mtx_unlock(&d->mtx);
ipc_dialer_fini(d);
}
@@ -166,7 +157,7 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
nni_ipc_conn * c;
nni_posix_pfd * pfd = NULL;
struct sockaddr_storage ss;
- size_t sslen;
+ size_t len;
int fd;
int rv;
@@ -174,7 +165,7 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
return;
}
- if (((sslen = nni_posix_nn2sockaddr(&ss, &d->sa)) == 0) ||
+ if (((len = nni_posix_nn2sockaddr(&ss, &d->sa)) == 0) ||
(ss.ss_family != AF_UNIX)) {
nni_aio_finish_error(aio, NNG_EADDRINVAL);
return;
@@ -185,23 +176,25 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
return;
}
- // This arranges for the fd to be in nonblocking mode, and adds the
- // pollfd to the list.
- if ((rv = nni_posix_pfd_init(&pfd, fd)) != 0) {
+ nni_atomic_inc64(&d->ref);
+
+ if ((rv = nni_posix_ipc_alloc(&c, d)) != 0) {
(void) close(fd);
+ nni_posix_ipc_dialer_rele(d);
nni_aio_finish_error(aio, rv);
return;
}
- if ((rv = nni_posix_ipc_init(&c, pfd)) != 0) {
- nni_posix_pfd_fini(pfd);
- nni_aio_finish_error(aio, rv);
- return;
+
+ // This arranges for the fd to be in non-blocking mode, and adds the
+ // poll fd to the list.
+ if ((rv = nni_posix_pfd_init(&pfd, fd)) != 0) {
+ goto error;
}
- c->dialer = d;
+
+ nni_posix_ipc_init(c, pfd);
nni_posix_pfd_set_cb(pfd, ipc_dialer_cb, c);
nni_mtx_lock(&d->mtx);
- d->refcnt++;
if (d->closed) {
rv = NNG_ECLOSED;
goto error;
@@ -209,7 +202,7 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
if ((rv = nni_aio_schedule(aio, ipc_dialer_cancel, d)) != 0) {
goto error;
}
- if (connect(fd, (void *) &ss, sslen) != 0) {
+ if (connect(fd, (void *) &ss, len) != 0) {
if (errno != EINPROGRESS) {
if (errno == ENOENT) {
// No socket present means nobody listening.
@@ -289,6 +282,9 @@ nni_ipc_dialer_alloc(nng_stream_dialer **dp, const nng_url *url)
d->sd.sd_dial = ipc_dialer_dial;
d->sd.sd_getx = ipc_dialer_getx;
d->sd.sd_setx = ipc_dialer_setx;
+ nni_atomic_init_bool(&d->fini);
+ nni_atomic_init64(&d->ref);
+ nni_atomic_inc64(&d->ref);
*dp = (void *) d;
return (0);
diff --git a/src/platform/posix/posix_ipclisten.c b/src/platform/posix/posix_ipclisten.c
index da3eab7b..4104be99 100644
--- a/src/platform/posix/posix_ipclisten.c
+++ b/src/platform/posix/posix_ipclisten.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -124,20 +124,22 @@ ipc_listener_doaccept(ipc_listener *l)
}
}
- if ((rv = nni_posix_pfd_init(&pfd, newfd)) != 0) {
- close(newfd);
+ if ((rv = nni_posix_ipc_alloc(&c, NULL)) != 0) {
+ (void) close(newfd);
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, rv);
continue;
}
- if ((rv = nni_posix_ipc_init(&c, pfd)) != 0) {
- nni_posix_pfd_fini(pfd);
+ if ((rv = nni_posix_pfd_init(&pfd, newfd)) != 0) {
+ nng_stream_free(&c->stream);
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, rv);
continue;
}
+ nni_posix_ipc_init(c, pfd);
+
nni_aio_list_remove(aio);
nni_posix_ipc_start(c);
nni_aio_set_output(aio, 0, c);
diff --git a/src/platform/posix/posix_pollq_epoll.c b/src/platform/posix/posix_pollq_epoll.c
index 8ec3bc3f..63cdaeb5 100644
--- a/src/platform/posix/posix_pollq_epoll.c
+++ b/src/platform/posix/posix_pollq_epoll.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Liam Staskawicz <liam@stask.net>
//
@@ -191,28 +191,27 @@ nni_posix_pfd_fini(nni_posix_pfd *pfd)
// We have to synchronize with the pollq thread (unless we are
// on that thread!)
- if (!nni_thr_is_self(&pq->thr)) {
+ NNI_ASSERT(!nni_thr_is_self(&pq->thr));
- uint64_t one = 1;
-
- nni_mtx_lock(&pq->mtx);
- nni_list_append(&pq->reapq, pfd);
+ uint64_t one = 1;
- // Wake the remote side. For now we assume this always
- // succeeds. The only failure modes here occur when we
- // have already excessively signaled this (2^64 times
- // with no read!!), or when the evfd is closed, or some
- // kernel bug occurs. Those errors would manifest as
- // a hang waiting for the poller to reap the pfd in fini,
- // if it were possible for them to occur. (Barring other
- // bugs, it isn't.)
- (void) write(pq->evfd, &one, sizeof(one));
+ nni_mtx_lock(&pq->mtx);
+ nni_list_append(&pq->reapq, pfd);
+
+ // Wake the remote side. For now we assume this always
+ // succeeds. The only failure modes here occur when we
+ // have already excessively signaled this (2^64 times
+ // with no read!!), or when the evfd is closed, or some
+ // kernel bug occurs. Those errors would manifest as
+ // a hang waiting for the poller to reap the pfd in fini,
+ // if it were possible for them to occur. (Barring other
+ // bugs, it isn't.)
+ (void) write(pq->evfd, &one, sizeof(one));
- while (!pfd->closed) {
- nni_cv_wait(&pfd->cv);
- }
- nni_mtx_unlock(&pq->mtx);
+ while (!pfd->closed) {
+ nni_cv_wait(&pfd->cv);
}
+ nni_mtx_unlock(&pq->mtx);
// We're exclusive now.
diff --git a/src/platform/posix/posix_pollq_kqueue.c b/src/platform/posix/posix_pollq_kqueue.c
index 72d306c7..299479ab 100644
--- a/src/platform/posix/posix_pollq_kqueue.c
+++ b/src/platform/posix/posix_pollq_kqueue.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Liam Staskawicz <liam@stask.net>
//
@@ -124,22 +124,24 @@ nni_posix_pfd_fini(nni_posix_pfd *pf)
nni_posix_pfd_close(pf);
- if (!nni_thr_is_self(&pq->thr)) {
- struct kevent ev;
- nni_mtx_lock(&pq->mtx);
- nni_list_append(&pq->reapq, pf);
- EV_SET(&ev, 0, EVFILT_USER, EV_ENABLE | EV_CLEAR, NOTE_TRIGGER,
- 0, NULL);
-
- // If this fails, the cleanup will stall. That should
- // only occur in a memory pressure situation, and it
- // will self-heal when the next event comes in.
- (void) kevent(pq->kq, &ev, 1, NULL, 0, NULL);
- while (!pf->closed) {
- nni_cv_wait(&pf->cv);
- }
- nni_mtx_unlock(&pq->mtx);
+ // All consumers take care to move finalization to the reap thread,
+ // unless they are synchronous on user threads.
+ NNI_ASSERT(!nni_thr_is_self(&pq->thr));
+
+ struct kevent ev;
+ nni_mtx_lock(&pq->mtx);
+ nni_list_append(&pq->reapq, pf);
+ EV_SET(
+ &ev, 0, EVFILT_USER, EV_ENABLE | EV_CLEAR, NOTE_TRIGGER, 0, NULL);
+
+ // If this fails, the cleanup will stall. That should
+ // only occur in a memory pressure situation, and it
+ // will self-heal when the next event comes in.
+ (void) kevent(pq->kq, &ev, 1, NULL, 0, NULL);
+ while (!pf->closed) {
+ nni_cv_wait(&pf->cv);
}
+ nni_mtx_unlock(&pq->mtx);
(void) close(pf->fd);
nni_cv_fini(&pf->cv);
diff --git a/src/platform/posix/posix_pollq_port.c b/src/platform/posix/posix_pollq_port.c
index 0a1110bf..bf628e47 100644
--- a/src/platform/posix/posix_pollq_port.c
+++ b/src/platform/posix/posix_pollq_port.c
@@ -105,22 +105,21 @@ nni_posix_pfd_fini(nni_posix_pfd *pfd)
nni_posix_pfd_close(pfd);
- if (!nni_thr_is_self(&pq->thr)) {
+ NNI_ASSERT(!nni_thr_is_self(&pq->thr));
- while (port_send(pq->port, 1, pfd) != 0) {
- if ((errno == EBADF) || (errno == EBADFD)) {
- pfd->closed = true;
- break;
- }
- sched_yield(); // try again later...
+ while (port_send(pq->port, 1, pfd) != 0) {
+ if ((errno == EBADF) || (errno == EBADFD)) {
+ pfd->closed = true;
+ break;
}
+ sched_yield(); // try again later...
+ }
- nni_mtx_lock(&pfd->mtx);
- while (!pfd->closed) {
- nni_cv_wait(&pfd->cv);
- }
- nni_mtx_unlock(&pfd->mtx);
+ nni_mtx_lock(&pfd->mtx);
+ while (!pfd->closed) {
+ nni_cv_wait(&pfd->cv);
}
+ nni_mtx_unlock(&pfd->mtx);
// We're exclusive now.
(void) close(pfd->fd);
diff --git a/src/platform/posix/posix_resolv_gai.c b/src/platform/posix/posix_resolv_gai.c
index 4b03a95e..a89c4623 100644
--- a/src/platform/posix/posix_resolv_gai.c
+++ b/src/platform/posix/posix_resolv_gai.c
@@ -42,6 +42,7 @@ typedef struct resolv_item resolv_item;
struct resolv_item {
int family;
int passive;
+ char name_buf[256];
char * name;
int proto;
int socktype;
@@ -67,7 +68,6 @@ resolv_cancel(nni_aio *aio, void *arg, int rv)
// so we can just discard everything.
nni_aio_list_remove(aio);
nni_mtx_unlock(&resolv_mtx);
- nni_strfree(item->name);
NNI_FREE_STRUCT(item);
} else {
// This case indicates the resolver is still processing our
@@ -255,14 +255,18 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
}
// NB: must remain valid until this is completed. So we have to
- // make our own copy.
+ // keep our own copy.
if (host == NULL) {
item->name = NULL;
- } else if ((item->name = nni_strdup(host)) == NULL) {
+
+ } else if (nni_strnlen(host, sizeof(item->name_buf)) >=
+ sizeof(item->name_buf)) {
NNI_FREE_STRUCT(item);
- nni_aio_finish_error(aio, NNG_ENOMEM);
- return;
+ nni_aio_finish_error(aio, NNG_EADDRINVAL);
+ } else {
+ nni_strlcpy(item->name_buf, host, sizeof(item->name_buf));
+ item->name = item->name_buf;
}
memset(&item->sa, 0, sizeof(item->sa));
@@ -282,7 +286,6 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
}
if (rv != 0) {
nni_mtx_unlock(&resolv_mtx);
- nni_strfree(item->name);
NNI_FREE_STRUCT(item);
nni_aio_finish_error(aio, rv);
return;
@@ -343,7 +346,6 @@ resolv_worker(void *unused)
nni_aio_set_sockaddr(aio, &item->sa);
nni_aio_finish(aio, rv, 0);
}
- nni_strfree(item->name);
NNI_FREE_STRUCT(item);
}
nni_mtx_unlock(&resolv_mtx);
diff --git a/src/platform/posix/posix_tcp.h b/src/platform/posix/posix_tcp.h
index e1a70bc3..87312dff 100644
--- a/src/platform/posix/posix_tcp.h
+++ b/src/platform/posix/posix_tcp.h
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Devolutions <info@devolutions.net>
//
@@ -27,7 +27,21 @@ struct nni_tcp_conn {
nni_tcp_dialer *dialer;
nni_reap_item reap;
};
-extern int nni_posix_tcp_init(nni_tcp_conn **, nni_posix_pfd *);
+
+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;
+ nni_atomic_u64 ref;
+ nni_atomic_bool fini;
+};
+
+extern int nni_posix_tcp_alloc(nni_tcp_conn **, nni_tcp_dialer *);
+extern void nni_posix_tcp_init(nni_tcp_conn *, nni_posix_pfd *);
extern void nni_posix_tcp_start(nni_tcp_conn *, int, int);
extern void nni_posix_tcp_dialer_rele(nni_tcp_dialer *);
diff --git a/src/platform/posix/posix_tcpconn.c b/src/platform/posix/posix_tcpconn.c
index 625fd7fd..2a209984 100644
--- a/src/platform/posix/posix_tcpconn.c
+++ b/src/platform/posix/posix_tcpconn.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -173,7 +173,9 @@ tcp_error(void *arg, int err)
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, err);
}
- nni_posix_pfd_close(c->pfd);
+ if (c->pfd != NULL) {
+ nni_posix_pfd_close(c->pfd);
+ }
nni_mtx_unlock(&c->mtx);
}
@@ -190,7 +192,9 @@ tcp_close(void *arg)
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, NNG_ECLOSED);
}
- nni_posix_pfd_close(c->pfd);
+ if (c->pfd != NULL) {
+ nni_posix_pfd_close(c->pfd);
+ }
}
nni_mtx_unlock(&c->mtx);
}
@@ -202,10 +206,9 @@ tcp_fini(void *arg)
{
nni_tcp_conn *c = arg;
tcp_close(c);
- nni_posix_pfd_fini(c->pfd);
- nni_mtx_lock(&c->mtx); // not strictly needed, but shut up TSAN
- c->pfd = NULL;
- nni_mtx_unlock(&c->mtx);
+ if (c->pfd != NULL) {
+ nni_posix_pfd_fini(c->pfd);
+ }
nni_mtx_fini(&c->mtx);
if (c->dialer != NULL) {
@@ -474,16 +477,15 @@ tcp_setx(void *arg, const char *name, const void *buf, size_t sz, nni_type t)
}
int
-nni_posix_tcp_init(nni_tcp_conn **cp, nni_posix_pfd *pfd)
+nni_posix_tcp_alloc(nni_tcp_conn **cp, nni_tcp_dialer *d)
{
nni_tcp_conn *c;
-
if ((c = NNI_ALLOC_STRUCT(c)) == NULL) {
return (NNG_ENOMEM);
}
c->closed = false;
- c->pfd = pfd;
+ c->dialer = d;
nni_mtx_init(&c->mtx);
nni_aio_list_init(&c->readq);
@@ -501,6 +503,12 @@ nni_posix_tcp_init(nni_tcp_conn **cp, nni_posix_pfd *pfd)
}
void
+nni_posix_tcp_init(nni_tcp_conn *c, nni_posix_pfd *pfd)
+{
+ c->pfd = pfd;
+}
+
+void
nni_posix_tcp_start(nni_tcp_conn *c, int nodelay, int keepalive)
{
// Configure the initial socket options.
diff --git a/src/platform/posix/posix_tcpdial.c b/src/platform/posix/posix_tcpdial.c
index 418eb17e..3fabc28a 100644
--- a/src/platform/posix/posix_tcpdial.c
+++ b/src/platform/posix/posix_tcpdial.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Devolutions <info@devolutions.net>
//
@@ -23,18 +23,6 @@
#include "posix_tcp.h"
-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;
- int refcnt;
- bool fini;
-};
-
// Dialer stuff.
int
nni_tcp_dialer_init(nni_tcp_dialer **dp)
@@ -47,6 +35,9 @@ nni_tcp_dialer_init(nni_tcp_dialer **dp)
nni_mtx_init(&d->mtx);
d->closed = false;
nni_aio_list_init(&d->connq);
+ nni_atomic_init_bool(&d->fini);
+ nni_atomic_init64(&d->ref);
+ nni_atomic_inc64(&d->ref);
*dp = d;
return (0);
}
@@ -84,26 +75,17 @@ void
nni_tcp_dialer_fini(nni_tcp_dialer *d)
{
nni_tcp_dialer_close(d);
- nni_mtx_lock(&d->mtx);
- d->fini = true;
- if (d->refcnt) {
- nni_mtx_unlock(&d->mtx);
- return;
- }
- nni_mtx_unlock(&d->mtx);
- tcp_dialer_fini(d);
+ nni_atomic_set_bool(&d->fini, true);
+ nni_posix_tcp_dialer_rele(d);
}
void
nni_posix_tcp_dialer_rele(nni_tcp_dialer *d)
{
- nni_mtx_lock(&d->mtx);
- d->refcnt--;
- if ((d->refcnt > 0) || (!d->fini)) {
- nni_mtx_unlock(&d->mtx);
+ if (((nni_atomic_dec64_nv(&d->ref) != 0)) ||
+ (!nni_atomic_get_bool(&d->fini))) {
return;
}
- nni_mtx_unlock(&d->mtx);
tcp_dialer_fini(d);
}
@@ -215,23 +197,25 @@ nni_tcp_dial(nni_tcp_dialer *d, nni_aio *aio)
return;
}
+ nni_atomic_inc64(&d->ref);
+
+ if ((rv = nni_posix_tcp_alloc(&c, d)) != 0) {
+ nni_aio_finish_error(aio, rv);
+ nni_posix_tcp_dialer_rele(d);
+ return;
+ }
+
// This arranges for the fd to be in non-blocking mode, and adds the
// poll fd to the list.
if ((rv = nni_posix_pfd_init(&pfd, fd)) != 0) {
(void) close(fd);
- nni_aio_finish_error(aio, rv);
- return;
- }
- if ((rv = nni_posix_tcp_init(&c, pfd)) != 0) {
- nni_posix_pfd_fini(pfd);
- nni_aio_finish_error(aio, rv);
- return;
+ goto error;
}
- c->dialer = d;
+
+ nni_posix_tcp_init(c, pfd);
nni_posix_pfd_set_cb(pfd, tcp_dialer_cb, c);
nni_mtx_lock(&d->mtx);
- d->refcnt++;
if (d->closed) {
rv = NNG_ECLOSED;
goto error;
diff --git a/src/platform/posix/posix_tcplisten.c b/src/platform/posix/posix_tcplisten.c
index 10867453..a463a198 100644
--- a/src/platform/posix/posix_tcplisten.c
+++ b/src/platform/posix/posix_tcplisten.c
@@ -1,5 +1,5 @@
//
-// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Devolutions <info@devolutions.net>
//
@@ -136,20 +136,23 @@ tcp_listener_doaccept(nni_tcp_listener *l)
}
}
- if ((rv = nni_posix_pfd_init(&pfd, newfd)) != 0) {
+ if ((rv = nni_posix_tcp_alloc(&c, NULL)) != 0) {
close(newfd);
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, rv);
continue;
}
- if ((rv = nni_posix_tcp_init(&c, pfd)) != 0) {
- nni_posix_pfd_fini(pfd);
+ if ((rv = nni_posix_pfd_init(&pfd, newfd)) != 0) {
+ close(newfd);
+ nng_stream_free(&c->stream);
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, rv);
continue;
}
+ nni_posix_tcp_init(c, pfd);
+
ka = l->keepalive ? 1 : 0;
nd = l->nodelay ? 1 : 0;
nni_aio_list_remove(aio);
diff --git a/src/supplemental/tcp/tcp.c b/src/supplemental/tcp/tcp.c
index 02a3351f..02d5d6ce 100644
--- a/src/supplemental/tcp/tcp.c
+++ b/src/supplemental/tcp/tcp.c
@@ -155,12 +155,15 @@ tcp_dialer_free(void *arg)
return;
}
+ nni_aio_stop(d->resaio);
+ nni_aio_stop(d->conaio);
+ nni_aio_fini(d->resaio);
+ nni_aio_fini(d->conaio);
+
if (d->d != NULL) {
nni_tcp_dialer_close(d->d);
nni_tcp_dialer_fini(d->d);
}
- nni_aio_fini(d->resaio);
- nni_aio_fini(d->conaio);
nni_mtx_fini(&d->mtx);
nni_strfree(d->host);
nni_strfree(d->port);
diff --git a/src/supplemental/tls/mbedtls/tls.c b/src/supplemental/tls/mbedtls/tls.c
index b7ed0575..d49c9de5 100644
--- a/src/supplemental/tls/mbedtls/tls.c
+++ b/src/supplemental/tls/mbedtls/tls.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -81,6 +81,7 @@ typedef struct {
nni_list sends; // upper side sends
nni_list recvs; // upper recv aios
nni_aio * handshake; // handshake aio (upper)
+ nni_reap_item reap;
} tls;
struct nng_tls_config {
@@ -279,36 +280,41 @@ tls_mkerr(int err)
// The common code should call this only after it has released
// it's upper layer stuff.
static void
-tls_free(void *arg)
+tls_reap(void *arg)
{
tls *tls = arg;
// Shut it all down first.
- if (tls != NULL) {
- if (tls->tcp != NULL) {
- nng_stream_close(tls->tcp);
- }
- nni_aio_stop(tls->tcp_send);
- nni_aio_stop(tls->tcp_recv);
- nni_aio_fini(tls->com.aio);
-
- // And finalize / free everything.
- nng_stream_free(tls->tcp);
- nni_aio_fini(tls->tcp_send);
- nni_aio_fini(tls->tcp_recv);
- mbedtls_ssl_free(&tls->ctx);
- nng_tls_config_free(tls->com.cfg);
-
- if (tls->recvbuf != NULL) {
- nni_free(tls->recvbuf, NNG_TLS_MAX_RECV_SIZE);
- }
- if (tls->sendbuf != NULL) {
- nni_free(tls->sendbuf, NNG_TLS_MAX_RECV_SIZE);
- }
- nni_mtx_fini(&tls->lk);
- memset(tls, 0xff, sizeof(*tls));
- NNI_FREE_STRUCT(tls);
+ if (tls->tcp != NULL) {
+ nng_stream_close(tls->tcp);
+ }
+ nni_aio_stop(tls->tcp_send);
+ nni_aio_stop(tls->tcp_recv);
+ nni_aio_fini(tls->com.aio);
+
+ // And finalize / free everything.
+ nng_stream_free(tls->tcp);
+ nni_aio_fini(tls->tcp_send);
+ nni_aio_fini(tls->tcp_recv);
+ mbedtls_ssl_free(&tls->ctx);
+ nng_tls_config_free(tls->com.cfg);
+
+ if (tls->recvbuf != NULL) {
+ nni_free(tls->recvbuf, NNG_TLS_MAX_RECV_SIZE);
+ }
+ if (tls->sendbuf != NULL) {
+ nni_free(tls->sendbuf, NNG_TLS_MAX_RECV_SIZE);
}
+ nni_mtx_fini(&tls->lk);
+ memset(tls, 0xff, sizeof(*tls));
+ NNI_FREE_STRUCT(tls);
+}
+
+static void
+tls_free(void *arg)
+{
+ tls *tls = arg;
+ nni_reap(&tls->reap, tls_reap, tls);
}
int