aboutsummaryrefslogtreecommitdiff
path: root/src/supplemental/tls/tls_common.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-12-12 17:55:48 -0800
committerGarrett D'Amore <garrett@damore.org>2024-12-12 17:55:48 -0800
commit81f5d3c6268ff91ee9c36c4cb34f6f9bfd54740d (patch)
treef9f21aa66bd22cfd95ae0c4b8abe57036c8fce0d /src/supplemental/tls/tls_common.c
parent371eedeeb6fafe628ae89b9ad2690fa3d6a57e8a (diff)
downloadnng-81f5d3c6268ff91ee9c36c4cb34f6f9bfd54740d.tar.gz
nng-81f5d3c6268ff91ee9c36c4cb34f6f9bfd54740d.tar.bz2
nng-81f5d3c6268ff91ee9c36c4cb34f6f9bfd54740d.zip
streams: add explicit stop functions
This allows us to explicitly stop streams, dialers, and listeners, before we start tearing down things. This hopefully will be useful in resolving use-after-free bugs in http, tls, and websockets. The new functions are not yet documented, but they are nng_stream_stop, nng_stream_dialer_stop, and nng_stream_listener_stop. They should be called after close, and before free. The close functions now close without blocking, but the stop function is allowed to block.
Diffstat (limited to 'src/supplemental/tls/tls_common.c')
-rw-r--r--src/supplemental/tls/tls_common.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c
index c04d03a5..a871e74e 100644
--- a/src/supplemental/tls/tls_common.c
+++ b/src/supplemental/tls/tls_common.c
@@ -126,6 +126,14 @@ tls_dialer_free(void *arg)
}
}
+static void
+tls_dialer_stop(void *arg)
+{
+ tls_dialer *d = arg;
+
+ nng_stream_dialer_stop(d->d);
+}
+
// For dialing, we need to have our own completion callback, instead of
// the user's completion callback.
@@ -281,6 +289,7 @@ nni_tls_dialer_alloc(nng_stream_dialer **dp, const nng_url *url)
d->ops.sd_close = tls_dialer_close;
d->ops.sd_free = tls_dialer_free;
+ d->ops.sd_stop = tls_dialer_stop;
d->ops.sd_dial = tls_dialer_dial;
d->ops.sd_get = tls_dialer_get;
d->ops.sd_set = tls_dialer_set;
@@ -307,6 +316,13 @@ tls_listener_close(void *arg)
}
static void
+tls_listener_stop(void *arg)
+{
+ tls_listener *l = arg;
+ nng_stream_listener_close(l->l);
+}
+
+static void
tls_listener_free(void *arg)
{
tls_listener *l;
@@ -436,6 +452,7 @@ nni_tls_listener_alloc(nng_stream_listener **lp, const nng_url *url)
}
l->ops.sl_free = tls_listener_free;
l->ops.sl_close = tls_listener_close;
+ l->ops.sl_stop = tls_listener_stop;
l->ops.sl_accept = tls_listener_accept;
l->ops.sl_listen = tls_listener_listen;
l->ops.sl_get = tls_listener_get;
@@ -526,6 +543,18 @@ tls_close(void *arg)
nng_stream_close(conn->tcp);
}
+static void
+tls_stop(void *arg)
+{
+ tls_conn *conn = arg;
+
+ tls_close(conn);
+ nng_stream_stop(conn->tcp);
+ nni_aio_stop(&conn->conn_aio);
+ nni_aio_stop(&conn->tcp_send);
+ nni_aio_stop(&conn->tcp_recv);
+}
+
static int
tls_get_verified(void *arg, void *buf, size_t *szp, nni_type t)
{
@@ -624,6 +653,7 @@ tls_alloc(tls_conn **conn_p, nng_tls_config *cfg, nng_aio *user_aio)
conn->stream.s_close = tls_close;
conn->stream.s_free = tls_free;
+ conn->stream.s_stop = tls_stop;
conn->stream.s_send = tls_send;
conn->stream.s_recv = tls_recv;
conn->stream.s_get = tls_get;
@@ -638,14 +668,7 @@ tls_reap(void *arg)
{
tls_conn *conn = arg;
- // Shut it all down first. We should be freed.
- if (conn->tcp != NULL) {
- nng_stream_close(conn->tcp);
- }
- nni_aio_stop(&conn->conn_aio);
- nni_aio_stop(&conn->tcp_send);
- nni_aio_stop(&conn->tcp_recv);
-
+ tls_stop(conn);
conn->ops.fini((void *) (conn + 1));
nni_aio_fini(&conn->conn_aio);
nni_aio_fini(&conn->tcp_send);