From 5cf750697624d4fd63cfe26921209d7c30e1a2d2 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Mon, 21 Jan 2019 22:40:10 -0800 Subject: fixes #872 create unified nng_stream API This is a major change, and includes changes to use a polymorphic stream API for all transports. There have been related bugs fixed along the way. Additionally the man pages have changed. The old non-polymorphic APIs are removed now. This is a breaking change, but the old APIs were never part of any released public API. --- src/platform/windows/win_ipc.h | 43 +------- src/platform/windows/win_ipcconn.c | 145 ++++++++++++++++---------- src/platform/windows/win_ipcdial.c | 149 +++++++++++++------------- src/platform/windows/win_ipclisten.c | 195 +++++++++++++++++++++++------------ src/platform/windows/win_resolv.c | 29 +++--- src/platform/windows/win_tcp.h | 15 +-- src/platform/windows/win_tcpconn.c | 195 +++++++++++++++-------------------- src/platform/windows/win_tcpdial.c | 34 ++++-- src/platform/windows/win_tcplisten.c | 8 +- 9 files changed, 424 insertions(+), 389 deletions(-) (limited to 'src/platform/windows') diff --git a/src/platform/windows/win_ipc.h b/src/platform/windows/win_ipc.h index e8e83957..d410b980 100644 --- a/src/platform/windows/win_ipc.h +++ b/src/platform/windows/win_ipc.h @@ -1,7 +1,7 @@ // // Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV -// Copyright 2018 Devolutions +// Copyright 2019 Devolutions // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -19,45 +19,6 @@ #define IPC_PIPE_PREFIX "\\\\.\\pipe\\" -struct nni_ipc_conn { - HANDLE f; - nni_win_io recv_io; - nni_win_io send_io; - nni_win_io conn_io; - nni_list recv_aios; - nni_list send_aios; - nni_aio * conn_aio; - nng_sockaddr sa; - bool dialer; - int recv_rv; - int send_rv; - int conn_rv; - bool closed; - nni_mtx mtx; - nni_cv cv; - nni_reap_item reap; -}; - -struct nni_ipc_dialer { - bool closed; // dialers are locked by the worker lock - nni_list aios; - nni_list_node node; // node on worker list -}; - -struct nni_ipc_listener { - char * path; - bool started; - bool closed; - HANDLE f; - SECURITY_ATTRIBUTES sec_attr; - nni_list aios; - nni_mtx mtx; - nni_cv cv; - nni_win_io io; - nni_sockaddr sa; - int rv; -}; - -extern int nni_win_ipc_conn_init(nni_ipc_conn **, HANDLE); +extern int nni_win_ipc_init(nng_stream **, HANDLE, const nng_sockaddr *, bool); #endif // NNG_PLATFORM_WIN_WINIPC_H diff --git a/src/platform/windows/win_ipcconn.c b/src/platform/windows/win_ipcconn.c index ded9ed76..4d267dd9 100644 --- a/src/platform/windows/win_ipcconn.c +++ b/src/platform/windows/win_ipcconn.c @@ -1,7 +1,7 @@ // -// Copyright 2018 Staysail Systems, Inc. +// Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV -// Copyright 2018 Devolutions +// Copyright 2019 Devolutions // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -15,10 +15,30 @@ #include -#define CONN(c) ((nni_ipc_conn *) (c)) +#define CONN(c) ((ipc_conn *) (c)) + +typedef struct ipc_conn { + nng_stream stream; + HANDLE f; + nni_win_io recv_io; + nni_win_io send_io; + nni_win_io conn_io; + nni_list recv_aios; + nni_list send_aios; + nni_aio * conn_aio; + nng_sockaddr sa; + bool dialer; + int recv_rv; + int send_rv; + int conn_rv; + bool closed; + nni_mtx mtx; + nni_cv cv; + nni_reap_item reap; +} ipc_conn; static void -ipc_recv_start(nni_ipc_conn *c) +ipc_recv_start(ipc_conn *c) { nni_aio *aio; unsigned idx; @@ -75,8 +95,8 @@ again: static void ipc_recv_cb(nni_win_io *io, int rv, size_t num) { - nni_aio * aio; - nni_ipc_conn *c = io->ptr; + nni_aio * aio; + ipc_conn *c = io->ptr; nni_mtx_lock(&c->mtx); if ((aio = nni_list_first(&c->recv_aios)) == NULL) { // Should indicate that it was closed. @@ -103,7 +123,7 @@ ipc_recv_cb(nni_win_io *io, int rv, size_t num) static void ipc_recv_cancel(nni_aio *aio, void *arg, int rv) { - nni_ipc_conn *c = arg; + ipc_conn *c = arg; nni_mtx_lock(&c->mtx); if (aio == nni_list_first(&c->recv_aios)) { c->recv_rv = rv; @@ -116,10 +136,11 @@ ipc_recv_cancel(nni_aio *aio, void *arg, int rv) nni_mtx_unlock(&c->mtx); } -void -nni_ipc_conn_recv(nni_ipc_conn *c, nni_aio *aio) +static void +ipc_recv(void *arg, nni_aio *aio) { - int rv; + ipc_conn *c = arg; + int rv; if (nni_aio_begin(aio) != 0) { return; @@ -143,7 +164,7 @@ nni_ipc_conn_recv(nni_ipc_conn *c, nni_aio *aio) } static void -ipc_send_start(nni_ipc_conn *c) +ipc_send_start(ipc_conn *c) { nni_aio *aio; unsigned idx; @@ -200,8 +221,8 @@ again: static void ipc_send_cb(nni_win_io *io, int rv, size_t num) { - nni_aio * aio; - nni_ipc_conn *c = io->ptr; + nni_aio * aio; + ipc_conn *c = io->ptr; nni_mtx_lock(&c->mtx); if ((aio = nni_list_first(&c->send_aios)) == NULL) { // Should indicate that it was closed. @@ -229,7 +250,7 @@ ipc_send_cb(nni_win_io *io, int rv, size_t num) static void ipc_send_cancel(nni_aio *aio, void *arg, int rv) { - nni_ipc_conn *c = arg; + ipc_conn *c = arg; nni_mtx_lock(&c->mtx); if (aio == nni_list_first(&c->send_aios)) { c->send_rv = rv; @@ -242,10 +263,11 @@ ipc_send_cancel(nni_aio *aio, void *arg, int rv) nni_mtx_unlock(&c->mtx); } -void -nni_ipc_conn_send(nni_ipc_conn *c, nni_aio *aio) +static void +ipc_send(void *arg, nni_aio *aio) { - int rv; + ipc_conn *c = arg; + int rv; if (nni_aio_begin(aio) != 0) { return; @@ -268,35 +290,10 @@ nni_ipc_conn_send(nni_ipc_conn *c, nni_aio *aio) nni_mtx_unlock(&c->mtx); } -int -nni_win_ipc_conn_init(nni_ipc_conn **connp, HANDLE p) -{ - nni_ipc_conn *c; - int rv; - - if ((c = NNI_ALLOC_STRUCT(c)) == NULL) { - return (NNG_ENOMEM); - } - c->f = INVALID_HANDLE_VALUE; - nni_mtx_init(&c->mtx); - nni_cv_init(&c->cv, &c->mtx); - nni_aio_list_init(&c->recv_aios); - nni_aio_list_init(&c->send_aios); - - if (((rv = nni_win_io_init(&c->recv_io, ipc_recv_cb, c)) != 0) || - ((rv = nni_win_io_init(&c->send_io, ipc_send_cb, c)) != 0)) { - nni_ipc_conn_fini(c); - return (rv); - } - - c->f = p; - *connp = c; - return (0); -} - -void -nni_ipc_conn_close(nni_ipc_conn *c) +static void +ipc_close(void *arg) { + ipc_conn *c = arg; nni_mtx_lock(&c->mtx); if (!c->closed) { c->closed = true; @@ -316,7 +313,7 @@ nni_ipc_conn_close(nni_ipc_conn *c) } static void -ipc_conn_reap(nni_ipc_conn *c) +ipc_conn_reap(ipc_conn *c) { nni_mtx_lock(&c->mtx); while ((!nni_list_empty(&c->recv_aios)) || @@ -337,10 +334,11 @@ ipc_conn_reap(nni_ipc_conn *c) NNI_FREE_STRUCT(c); } -void -nni_ipc_conn_fini(nni_ipc_conn *c) +static void +ipc_free(void *arg) { - nni_ipc_conn_close(c); + ipc_conn *c = arg; + ipc_close(c); nni_reap(&c->reap, (nni_cb) ipc_conn_reap, CONN(c)); } @@ -386,16 +384,51 @@ static const nni_option ipc_conn_options[] = { }, }; -int -nni_ipc_conn_setopt(nni_ipc_conn *c, const char *name, const void *val, - size_t sz, nni_opt_type t) +static int +ipc_setx(void *arg, const char *nm, const void *val, size_t sz, nni_opt_type t) +{ + ipc_conn *c = arg; + return (nni_setopt(ipc_conn_options, nm, c, val, sz, t)); +} + +static int +ipc_getx(void *arg, const char *nm, void *val, size_t *szp, nni_opt_type t) { - return (nni_setopt(ipc_conn_options, name, c, val, sz, t)); + ipc_conn *c = arg; + return (nni_getopt(ipc_conn_options, nm, c, val, szp, t)); } int -nni_ipc_conn_getopt( - nni_ipc_conn *c, const char *name, void *val, size_t *szp, nni_opt_type t) +nni_win_ipc_init( + nng_stream **connp, HANDLE p, const nng_sockaddr *sa, bool dialer) { - return (nni_getopt(ipc_conn_options, name, c, val, szp, t)); + ipc_conn *c; + int rv; + + if ((c = NNI_ALLOC_STRUCT(c)) == NULL) { + return (NNG_ENOMEM); + } + c->f = INVALID_HANDLE_VALUE; + nni_mtx_init(&c->mtx); + nni_cv_init(&c->cv, &c->mtx); + nni_aio_list_init(&c->recv_aios); + nni_aio_list_init(&c->send_aios); + c->dialer = dialer; + c->sa = *sa; + c->stream.s_free = ipc_free; + c->stream.s_close = ipc_close; + c->stream.s_send = ipc_send; + c->stream.s_recv = ipc_recv; + c->stream.s_getx = ipc_getx; + c->stream.s_setx = ipc_setx; + + if (((rv = nni_win_io_init(&c->recv_io, ipc_recv_cb, c)) != 0) || + ((rv = nni_win_io_init(&c->send_io, ipc_send_cb, c)) != 0)) { + ipc_free(c); + return (rv); + } + + c->f = p; + *connp = (void *) c; + return (0); } diff --git a/src/platform/windows/win_ipcdial.c b/src/platform/windows/win_ipcdial.c index 98d848ae..be2a82b3 100644 --- a/src/platform/windows/win_ipcdial.c +++ b/src/platform/windows/win_ipcdial.c @@ -1,7 +1,7 @@ // -// Copyright 2018 Staysail Systems, Inc. +// Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV -// Copyright 2018 Devolutions +// Copyright 2019 Devolutions // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -15,19 +15,14 @@ #include -int -nni_ipc_dialer_init(nni_ipc_dialer **dp) -{ - nni_ipc_dialer *d; - - if ((d = NNI_ALLOC_STRUCT(d)) == NULL) { - return (NNG_ENOMEM); - } - d->closed = false; - nni_aio_list_init(&d->aios); - *dp = d; - return (0); -} +typedef struct ipc_dialer { + nng_stream_dialer sd; + bool closed; // dialers are locked by the worker lock + nni_list aios; + nni_list_node node; // node on worker list + char * path; + nni_sockaddr sa; +} ipc_dialer; // Windows IPC is a bit different on the client side. There is no // support for asynchronous connection, but we can fake it with a @@ -52,7 +47,7 @@ ipc_dial_thr(void *arg) nni_mtx_lock(&w->mtx); for (;;) { - nni_ipc_dialer *d; + ipc_dialer *d; if (w->exit) { break; @@ -63,21 +58,19 @@ ipc_dial_thr(void *arg) } while ((d = nni_list_first(&w->workers)) != NULL) { - nni_ipc_conn *c; - nni_aio * aio; - HANDLE f; - int rv; - char * path; + nng_stream *c; + nni_aio * aio; + HANDLE f; + int rv; if ((aio = nni_list_first(&d->aios)) == NULL) { nni_list_remove(&w->workers, d); continue; } - path = nni_aio_get_prov_extra(aio, 0); - - f = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + f = CreateFileA(d->path, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, + NULL); if (f == INVALID_HANDLE_VALUE) { switch ((rv = GetLastError())) { @@ -99,29 +92,20 @@ ipc_dial_thr(void *arg) break; } nni_list_remove(&d->aios, aio); - nni_aio_set_prov_extra(aio, 0, NULL); - nni_strfree(path); nni_aio_finish_error(aio, rv); continue; } nni_list_remove(&d->aios, aio); - nni_aio_set_prov_extra(aio, 0, NULL); if (((rv = nni_win_io_register(f)) != 0) || - ((rv = nni_win_ipc_conn_init(&c, f)) != 0)) { + ((rv = nni_win_ipc_init(&c, f, &d->sa, true)) != + 0)) { DisconnectNamedPipe(f); CloseHandle(f); nni_aio_finish_error(aio, rv); - nni_strfree(path); continue; } - c->dialer = true; - c->sa.s_ipc.sa_family = NNG_AF_IPC; - snprintf(c->sa.s_ipc.sa_path, - sizeof(c->sa.s_ipc.sa_path), "%s", - path + strlen(IPC_PIPE_PREFIX)); - nni_strfree(path); nni_aio_set_output(aio, 0, c); nni_aio_finish(aio, 0, 0); } @@ -140,27 +124,23 @@ ipc_dial_thr(void *arg) static void ipc_dial_cancel(nni_aio *aio, void *arg, int rv) { - nni_ipc_dialer *d = arg; - ipc_dial_work * w = &ipc_connecter; + ipc_dialer * d = arg; + ipc_dial_work *w = &ipc_connecter; nni_mtx_lock(&w->mtx); if (nni_aio_list_active(aio)) { - char *path; if (nni_list_active(&w->waiters, d)) { nni_list_remove(&w->waiters, d); nni_cv_wake(&w->cv); } nni_aio_list_remove(aio); - path = nni_aio_get_prov_extra(aio, 0); - nni_aio_set_prov_extra(aio, 0, NULL); - nni_strfree(path); nni_aio_finish_error(aio, rv); } nni_mtx_unlock(&w->mtx); } -void -nni_ipc_dialer_dial(nni_ipc_dialer *d, const nni_sockaddr *sa, nni_aio *aio) +static void +ipc_dialer_dial(ipc_dialer *d, nni_aio *aio) { ipc_dial_work *w = &ipc_connecter; char * path; @@ -169,12 +149,8 @@ nni_ipc_dialer_dial(nni_ipc_dialer *d, const nni_sockaddr *sa, nni_aio *aio) if (nni_aio_begin(aio) != 0) { return; } - if (sa->s_family != NNG_AF_IPC) { - nni_aio_finish_error(aio, NNG_EADDRINVAL); - return; - } if ((rv = nni_asprintf( - &path, IPC_PIPE_PREFIX "%s", sa->s_ipc.sa_path)) != 0) { + &path, IPC_PIPE_PREFIX "%s", d->sa.s_ipc.sa_path)) != 0) { nni_aio_finish_error(aio, rv); return; } @@ -182,19 +158,16 @@ nni_ipc_dialer_dial(nni_ipc_dialer *d, const nni_sockaddr *sa, nni_aio *aio) nni_mtx_lock(&w->mtx); if ((rv = nni_aio_schedule(aio, ipc_dial_cancel, d)) != 0) { nni_mtx_unlock(&w->mtx); - nni_strfree(path); nni_aio_finish_error(aio, rv); return; } if (d->closed) { nni_mtx_unlock(&w->mtx); - nni_strfree(path); nni_aio_finish_error(aio, NNG_ECLOSED); return; } - nni_aio_set_prov_extra(aio, 0, path); nni_list_append(&d->aios, aio); if (nni_list_first(&d->aios) == aio) { nni_list_append(&w->waiters, d); @@ -203,16 +176,10 @@ nni_ipc_dialer_dial(nni_ipc_dialer *d, const nni_sockaddr *sa, nni_aio *aio) nni_mtx_unlock(&w->mtx); } -void -nni_ipc_dialer_fini(nni_ipc_dialer *d) -{ - nni_ipc_dialer_close(d); - NNI_FREE_STRUCT(d); -} - -void -nni_ipc_dialer_close(nni_ipc_dialer *d) +static void +ipc_dialer_close(void *arg) { + ipc_dialer * d = arg; ipc_dial_work *w = &ipc_connecter; nni_aio * aio; @@ -228,6 +195,17 @@ nni_ipc_dialer_close(nni_ipc_dialer *d) nni_mtx_unlock(&w->mtx); } +static void +ipc_dialer_free(void *arg) +{ + ipc_dialer *d = arg; + ipc_dialer_close(d); + if (d->path) { + nni_strfree(d->path); + } + NNI_FREE_STRUCT(d); +} + static const nni_option ipc_dialer_options[] = { { .o_name = NULL, @@ -235,17 +213,50 @@ static const nni_option ipc_dialer_options[] = { }; int -nni_ipc_dialer_setopt(nni_ipc_dialer *d, const char *name, const void *buf, - size_t sz, nni_type t) +ipc_dialer_setx( + void *arg, const char *nm, const void *buf, size_t sz, nni_type t) +{ + ipc_dialer *d = arg; + return (nni_setopt(ipc_dialer_options, nm, d, buf, sz, t)); +} + +int +ipc_dialer_getx(void *arg, const char *nm, void *buf, size_t *szp, nni_type t) { - return (nni_setopt(ipc_dialer_options, name, d, buf, sz, t)); + ipc_dialer *d = arg; + return (nni_getopt(ipc_dialer_options, nm, d, buf, szp, t)); } int -nni_ipc_dialer_getopt( - nni_ipc_dialer *d, const char *name, void *buf, size_t *szp, nni_type t) +nni_ipc_dialer_alloc(nng_stream_dialer **dp, const nng_url *url) { - return (nni_getopt(ipc_dialer_options, name, d, buf, szp, t)); + ipc_dialer *d; + int rv; + + if ((strcmp(url->u_scheme, "ipc") != 0) || (url->u_path == NULL) || + (strlen(url->u_path) == 0)) { + return (NNG_EADDRINVAL); + } + if ((d = NNI_ALLOC_STRUCT(d)) == NULL) { + return (NNG_ENOMEM); + } + + if ((rv = nni_asprintf(&d->path, IPC_PIPE_PREFIX "%s", url->u_path)) != + 0) { + NNI_FREE_STRUCT(d); + return (rv); + } + snprintf(d->sa.s_ipc.sa_path, NNG_MAXADDRLEN, "%s", url->u_path); + d->sa.s_ipc.sa_family = NNG_AF_IPC; + d->closed = false; + d->sd.sd_free = ipc_dialer_free; + d->sd.sd_close = ipc_dialer_close; + d->sd.sd_dial = ipc_dialer_dial; + d->sd.sd_getx = ipc_dialer_getx; + d->sd.sd_setx = ipc_dialer_setx; + nni_aio_list_init(&d->aios); + *dp = (void *) d; + return (0); } int @@ -254,8 +265,8 @@ nni_win_ipc_sysinit(void) int rv; ipc_dial_work *worker = &ipc_connecter; - NNI_LIST_INIT(&worker->workers, nni_ipc_dialer, node); - NNI_LIST_INIT(&worker->waiters, nni_ipc_dialer, node); + NNI_LIST_INIT(&worker->workers, ipc_dialer, node); + NNI_LIST_INIT(&worker->waiters, ipc_dialer, node); nni_mtx_init(&worker->mtx); nni_cv_init(&worker->cv, &worker->mtx); diff --git a/src/platform/windows/win_ipclisten.c b/src/platform/windows/win_ipclisten.c index 4b3660ec..a3922d06 100644 --- a/src/platform/windows/win_ipclisten.c +++ b/src/platform/windows/win_ipclisten.c @@ -1,7 +1,7 @@ // -// Copyright 2018 Staysail Systems, Inc. +// Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV -// Copyright 2018 Devolutions +// Copyright 2019 Devolutions // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -15,12 +15,27 @@ #include +typedef struct { + nng_stream_listener sl; + char * path; + bool started; + bool closed; + HANDLE f; + SECURITY_ATTRIBUTES sec_attr; + nni_list aios; + nni_mtx mtx; + nni_cv cv; + nni_win_io io; + nni_sockaddr sa; + int rv; +} ipc_listener; + static void -ipc_accept_done(nni_ipc_listener *l, int rv) +ipc_accept_done(ipc_listener *l, int rv) { - nni_aio * aio; - HANDLE f; - nni_ipc_conn *c; + nni_aio * aio; + HANDLE f; + nng_stream *c; aio = nni_list_first(&l->aios); nni_list_remove(&l->aios, aio); @@ -50,24 +65,21 @@ ipc_accept_done(nni_ipc_listener *l, int rv) } if (((rv = nni_win_io_register(f)) != 0) || - ((rv = nni_win_ipc_conn_init(&c, l->f)) != 0)) { + ((rv = nni_win_ipc_init(&c, l->f, &l->sa, false)) != 0)) { DisconnectNamedPipe(l->f); DisconnectNamedPipe(f); CloseHandle(f); nni_aio_finish_error(aio, rv); return; } - l->f = f; - c->sa.s_ipc.sa_family = NNG_AF_IPC; - snprintf(c->sa.s_ipc.sa_path, sizeof(c->sa.s_ipc.sa_path), "%s", - l->path + strlen(IPC_PIPE_PREFIX)); - c->dialer = false; + // Install the replacement pipe. + l->f = f; nni_aio_set_output(aio, 0, c); nni_aio_finish(aio, 0, 0); } static void -ipc_accept_start(nni_ipc_listener *l) +ipc_accept_start(ipc_listener *l) { nni_aio *aio; @@ -102,7 +114,7 @@ ipc_accept_start(nni_ipc_listener *l) static void ipc_accept_cb(nni_win_io *io, int rv, size_t cnt) { - nni_ipc_listener *l = io->ptr; + ipc_listener *l = io->ptr; NNI_ARG_UNUSED(cnt); @@ -122,37 +134,12 @@ ipc_accept_cb(nni_win_io *io, int rv, size_t cnt) nni_mtx_unlock(&l->mtx); } -int -nni_ipc_listener_init(nni_ipc_listener **lp) -{ - nni_ipc_listener *l; - int rv; - - if ((l = NNI_ALLOC_STRUCT(l)) == NULL) { - return (NNG_ENOMEM); - } - if ((rv = nni_win_io_init(&l->io, ipc_accept_cb, l)) != 0) { - NNI_FREE_STRUCT(l); - return (rv); - } - l->started = false; - l->closed = false; - l->sec_attr.nLength = sizeof(l->sec_attr); - l->sec_attr.lpSecurityDescriptor = NULL; - l->sec_attr.bInheritHandle = FALSE; - nni_aio_list_init(&l->aios); - nni_mtx_init(&l->mtx); - nni_cv_init(&l->cv, &l->mtx); - *lp = l; - return (0); -} - static int ipc_listener_set_sec_desc(void *arg, const void *buf, size_t sz, nni_type t) { - nni_ipc_listener *l = arg; - void * desc; - int rv; + ipc_listener *l = arg; + void * desc; + int rv; if ((rv = nni_copyin_ptr(&desc, buf, sz, t)) != 0) { return (rv); @@ -160,22 +147,20 @@ ipc_listener_set_sec_desc(void *arg, const void *buf, size_t sz, nni_type t) if (!IsValidSecurityDescriptor((SECURITY_DESCRIPTOR *) desc)) { return (NNG_EINVAL); } - if (l != NULL) { - nni_mtx_lock(&l->mtx); - if (l->started) { - nni_mtx_unlock(&l->mtx); - return (NNG_EBUSY); - } - l->sec_attr.lpSecurityDescriptor = desc; + nni_mtx_lock(&l->mtx); + if (l->started) { nni_mtx_unlock(&l->mtx); + return (NNG_EBUSY); } + l->sec_attr.lpSecurityDescriptor = desc; + nni_mtx_unlock(&l->mtx); return (0); } static int ipc_listener_get_addr(void *arg, void *buf, size_t *szp, nni_type t) { - nni_ipc_listener *l = arg; + ipc_listener *l = arg; return ((nni_copyout_sockaddr(&l->sa, buf, szp, t))); } @@ -194,25 +179,28 @@ static const nni_option ipc_listener_options[] = { }; int -nni_ipc_listener_setopt(nni_ipc_listener *l, const char *name, const void *buf, - size_t sz, nni_type t) +ipc_listener_setx( + void *arg, const char *name, const void *buf, size_t sz, nni_type t) { + ipc_listener *l = arg; return (nni_setopt(ipc_listener_options, name, l, buf, sz, t)); } int -nni_ipc_listener_getopt( - nni_ipc_listener *l, const char *name, void *buf, size_t *szp, nni_type t) +ipc_listener_getx( + void *arg, const char *name, void *buf, size_t *szp, nni_type t) { + ipc_listener *l = arg; return (nni_getopt(ipc_listener_options, name, l, buf, szp, t)); } -int -nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) +static int +ipc_listener_listen(void *arg) { - int rv; - HANDLE f; - char * path; + ipc_listener *l = arg; + int rv; + HANDLE f; + char * path; nni_mtx_lock(&l->mtx); if (l->started) { @@ -223,7 +211,7 @@ nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) nni_mtx_unlock(&l->mtx); return (NNG_ECLOSED); } - rv = nni_asprintf(&path, IPC_PIPE_PREFIX "%s", sa->s_ipc.sa_path); + rv = nni_asprintf(&path, IPC_PIPE_PREFIX "%s", l->sa.s_ipc.sa_path); if (rv != 0) { nni_mtx_unlock(&l->mtx); return (rv); @@ -255,7 +243,6 @@ nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) l->f = f; l->path = path; l->started = true; - l->sa = *sa; nni_mtx_unlock(&l->mtx); return (0); } @@ -263,7 +250,7 @@ nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) static void ipc_accept_cancel(nni_aio *aio, void *arg, int rv) { - nni_ipc_listener *l = arg; + ipc_listener *l = arg; nni_mtx_unlock(&l->mtx); if (aio == nni_list_first(&l->aios)) { @@ -277,9 +264,10 @@ ipc_accept_cancel(nni_aio *aio, void *arg, int rv) nni_mtx_unlock(&l->mtx); } -void -nni_ipc_listener_accept(nni_ipc_listener *l, nni_aio *aio) +static void +ipc_listener_accept(void *arg, nni_aio *aio) { + ipc_listener *l = arg; if (nni_aio_begin(aio) != 0) { return; } @@ -301,9 +289,10 @@ nni_ipc_listener_accept(nni_ipc_listener *l, nni_aio *aio) nni_mtx_unlock(&l->mtx); } -void -nni_ipc_listener_close(nni_ipc_listener *l) +static void +ipc_listener_close(void *arg) { + ipc_listener *l = arg; nni_mtx_lock(&l->mtx); if (!l->closed) { l->closed = true; @@ -316,9 +305,10 @@ nni_ipc_listener_close(nni_ipc_listener *l) nni_mtx_unlock(&l->mtx); } -void -nni_ipc_listener_fini(nni_ipc_listener *l) +static void +ipc_listener_free(void *arg) { + ipc_listener *l = arg; nni_mtx_lock(&l->mtx); while (!nni_list_empty(&l->aios)) { nni_cv_wait(&l->cv); @@ -330,3 +320,72 @@ nni_ipc_listener_fini(nni_ipc_listener *l) nni_mtx_fini(&l->mtx); NNI_FREE_STRUCT(l); } + +int +nni_ipc_listener_alloc(nng_stream_listener **lp, const nng_url *url) +{ + ipc_listener *l; + int rv; + + if ((strcmp(url->u_scheme, "ipc") != 0) || (url->u_path == NULL) || + (strlen(url->u_path) == 0)) { + return (NNG_EADDRINVAL); + } + if ((l = NNI_ALLOC_STRUCT(l)) == NULL) { + return (NNG_ENOMEM); + } + if ((rv = nni_win_io_init(&l->io, ipc_accept_cb, l)) != 0) { + NNI_FREE_STRUCT(l); + return (rv); + } + l->started = false; + l->closed = false; + l->sec_attr.nLength = sizeof(l->sec_attr); + l->sec_attr.lpSecurityDescriptor = NULL; + l->sec_attr.bInheritHandle = FALSE; + l->sa.s_ipc.sa_family = NNG_AF_IPC; + l->sl.sl_free = ipc_listener_free; + l->sl.sl_close = ipc_listener_close; + l->sl.sl_listen = ipc_listener_listen; + l->sl.sl_accept = ipc_listener_accept; + l->sl.sl_getx = ipc_listener_getx; + l->sl.sl_setx = ipc_listener_setx; + snprintf(l->sa.s_ipc.sa_path, NNG_MAXADDRLEN, "%s", url->u_path); + nni_aio_list_init(&l->aios); + nni_mtx_init(&l->mtx); + nni_cv_init(&l->cv, &l->mtx); + *lp = (void *) l; + return (0); +} + +static int +ipc_check_sec_desc(const void *buf, size_t sz, nni_type t) +{ + void *desc; + int rv; + + if ((rv = nni_copyin_ptr(&desc, buf, sz, t)) != 0) { + return (rv); + } + if (!IsValidSecurityDescriptor((SECURITY_DESCRIPTOR *) desc)) { + return (NNG_EINVAL); + } + + return (0); +} + +static const nni_chkoption ipc_chkopts[] = { + { + .o_name = NNG_OPT_IPC_SECURITY_DESCRIPTOR, + .o_check = ipc_check_sec_desc, + }, + { + .o_name = NULL, + }, +}; + +int +nni_ipc_checkopt(const char *name, const void *data, size_t sz, nni_type t) +{ + return (nni_chkopt(ipc_chkopts, name, data, sz, t)); +} diff --git a/src/platform/windows/win_resolv.c b/src/platform/windows/win_resolv.c index d361a1e8..e01dba3b 100644 --- a/src/platform/windows/win_resolv.c +++ b/src/platform/windows/win_resolv.c @@ -134,25 +134,27 @@ resolv_task(resolv_item *item) } } - if (probe != NULL) { + if ((probe != NULL) && (item->aio != NULL)) { struct sockaddr_in * sin; struct sockaddr_in6 *sin6; - nni_sockaddr * sa = &item->sa; + nni_sockaddr sa; switch (probe->ai_addr->sa_family) { case AF_INET: - rv = 0; - sin = (void *) probe->ai_addr; - sa->s_in.sa_family = NNG_AF_INET; - sa->s_in.sa_port = item->port; - sa->s_in.sa_addr = sin->sin_addr.s_addr; + rv = 0; + sin = (void *) probe->ai_addr; + sa.s_in.sa_family = NNG_AF_INET; + sa.s_in.sa_port = item->port; + sa.s_in.sa_addr = sin->sin_addr.s_addr; + nni_aio_set_sockaddr(item->aio, &sa); break; case AF_INET6: - rv = 0; - sin6 = (void *) probe->ai_addr; - sa->s_in6.sa_family = NNG_AF_INET6; - sa->s_in6.sa_port = item->port; - memcpy(sa->s_in6.sa_addr, sin6->sin6_addr.s6_addr, 16); + rv = 0; + sin6 = (void *) probe->ai_addr; + sa.s_in6.sa_family = NNG_AF_INET6; + sa.s_in6.sa_port = item->port; + memcpy(sa.s_in6.sa_addr, sin6->sin6_addr.s6_addr, 16); + nni_aio_set_sockaddr(item->aio, &sa); break; } } @@ -294,10 +296,9 @@ resolv_worker(void *notused) // Check to make sure we were not canceled. if ((aio = item->aio) != NULL) { - nng_sockaddr *sa = nni_aio_get_input(aio, 0); nni_aio_set_prov_extra(aio, 0, NULL); item->aio = NULL; - memcpy(sa, &item->sa, sizeof(*sa)); + nni_aio_finish(aio, rv, 0); NNI_FREE_STRUCT(item); diff --git a/src/platform/windows/win_tcp.h b/src/platform/windows/win_tcp.h index 1b34aa29..b37b2353 100644 --- a/src/platform/windows/win_tcp.h +++ b/src/platform/windows/win_tcp.h @@ -1,7 +1,7 @@ // // Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV -// Copyright 2018 Devolutions +// Copyright 2019 Devolutions // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -17,6 +17,7 @@ #include "core/nng_impl.h" struct nni_tcp_conn { + nng_stream ops; SOCKET s; nni_win_io recv_io; nni_win_io send_io; @@ -37,18 +38,6 @@ struct nni_tcp_conn { nni_cv cv; }; -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; - nni_reap_item reap; -}; - struct nni_tcp_listener { SOCKET s; nni_list aios; diff --git a/src/platform/windows/win_tcpconn.c b/src/platform/windows/win_tcpconn.c index 54d22dea..c77bbc72 100644 --- a/src/platform/windows/win_tcpconn.c +++ b/src/platform/windows/win_tcpconn.c @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. +// Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // Copyright 2018 Devolutions // @@ -110,8 +110,8 @@ tcp_recv_cancel(nni_aio *aio, void *arg, int rv) nni_mtx_unlock(&c->mtx); } -void -nni_tcp_conn_recv(nni_tcp_conn *c, nni_aio *aio) +static void +tcp_recv(nni_tcp_conn *c, nni_aio *aio) { int rv; @@ -225,10 +225,11 @@ tcp_send_cb(nni_win_io *io, int rv, size_t num) nni_aio_finish_synch(aio, rv, num); } -void -nni_tcp_conn_send(nni_tcp_conn *c, nni_aio *aio) +static void +tcp_send(void *arg, nni_aio *aio) { - int rv; + nni_tcp_conn *c = arg; + int rv; if (nni_aio_begin(aio) != 0) { return; @@ -251,49 +252,10 @@ nni_tcp_conn_send(nni_tcp_conn *c, nni_aio *aio) nni_mtx_unlock(&c->mtx); } -int -nni_win_tcp_conn_init(nni_tcp_conn **connp, SOCKET s) -{ - nni_tcp_conn *c; - int rv; - BOOL yes; - DWORD no; - - // Don't inherit the handle (CLOEXEC really). - SetHandleInformation((HANDLE) s, HANDLE_FLAG_INHERIT, 0); - - if ((c = NNI_ALLOC_STRUCT(c)) == NULL) { - return (NNG_ENOMEM); - } - c->s = INVALID_SOCKET; - nni_mtx_init(&c->mtx); - nni_cv_init(&c->cv, &c->mtx); - nni_aio_list_init(&c->recv_aios); - nni_aio_list_init(&c->send_aios); - c->conn_aio = NULL; - - if (((rv = nni_win_io_init(&c->recv_io, tcp_recv_cb, c)) != 0) || - ((rv = nni_win_io_init(&c->send_io, tcp_send_cb, c)) != 0) || - ((rv = nni_win_io_register((HANDLE) s)) != 0)) { - nni_tcp_conn_fini(c); - return (rv); - } - - no = 0; - (void) setsockopt( - s, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &no, sizeof(no)); - yes = 1; - (void) setsockopt( - s, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(yes)); - - c->s = s; - *connp = c; - return (0); -} - -void -nni_tcp_conn_close(nni_tcp_conn *c) +static void +tcp_close(void *arg) { + nni_tcp_conn *c = arg; nni_mtx_lock(&c->mtx); if (!c->closed) { c->closed = true; @@ -310,50 +272,8 @@ nni_tcp_conn_close(nni_tcp_conn *c) nni_mtx_unlock(&c->mtx); } -int -nni_tcp_conn_peername(nni_tcp_conn *c, nni_sockaddr *sa) -{ - if (nni_win_sockaddr2nn(sa, &c->peername) < 0) { - return (NNG_EADDRINVAL); - } - return (0); -} - -int -nni_tcp_conn_sockname(nni_tcp_conn *c, nni_sockaddr *sa) -{ - if (nni_win_sockaddr2nn(sa, &c->sockname) < 0) { - return (NNG_EADDRINVAL); - } - return (0); -} - -int -nni_tcp_conn_set_nodelay(nni_tcp_conn *c, bool val) -{ - BOOL b; - b = val ? TRUE : FALSE; - if (setsockopt( - c->s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b)) != 0) { - return (nni_win_error(WSAGetLastError())); - } - return (0); -} - -int -nni_tcp_conn_set_keepalive(nni_tcp_conn *c, bool val) -{ - BOOL b; - 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_peername(void *arg, void *buf, size_t *szp, nni_type t) +tcp_get_peername(void *arg, void *buf, size_t *szp, nni_type t) { nni_tcp_conn *c = arg; nng_sockaddr sa; @@ -365,7 +285,7 @@ tcp_conn_get_peername(void *arg, void *buf, size_t *szp, nni_type t) } static int -tcp_conn_get_sockname(void *arg, void *buf, size_t *szp, nni_type t) +tcp_get_sockname(void *arg, void *buf, size_t *szp, nni_type t) { nni_tcp_conn *c = arg; nng_sockaddr sa; @@ -377,7 +297,7 @@ tcp_conn_get_sockname(void *arg, void *buf, size_t *szp, nni_type t) } static int -tcp_conn_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t) +tcp_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t) { nni_tcp_conn *c = arg; bool val; @@ -395,7 +315,7 @@ tcp_conn_set_nodelay(void *arg, const void *buf, size_t sz, nni_type t) } static int -tcp_conn_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t) +tcp_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t) { nni_tcp_conn *c = arg; bool val; @@ -414,7 +334,7 @@ tcp_conn_set_keepalive(void *arg, const void *buf, size_t sz, nni_type t) } static int -tcp_conn_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t) +tcp_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t) { nni_tcp_conn *c = arg; BOOL b = 0; @@ -428,7 +348,7 @@ tcp_conn_get_nodelay(void *arg, void *buf, size_t *szp, nni_type t) } static int -tcp_conn_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t) +tcp_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t) { nni_tcp_conn *c = arg; BOOL b = 0; @@ -441,48 +361,49 @@ tcp_conn_get_keepalive(void *arg, void *buf, size_t *szp, nni_type t) return (nni_copyout_bool(b, buf, szp, t)); } -static const nni_option tcp_conn_options[] = { +static const nni_option tcp_options[] = { { .o_name = NNG_OPT_REMADDR, - .o_get = tcp_conn_get_peername, + .o_get = tcp_get_peername, }, { .o_name = NNG_OPT_LOCADDR, - .o_get = tcp_conn_get_sockname, + .o_get = tcp_get_sockname, }, { .o_name = NNG_OPT_TCP_NODELAY, - .o_get = tcp_conn_get_nodelay, - .o_set = tcp_conn_set_nodelay, + .o_get = tcp_get_nodelay, + .o_set = tcp_set_nodelay, }, { .o_name = NNG_OPT_TCP_KEEPALIVE, - .o_get = tcp_conn_get_keepalive, - .o_set = tcp_conn_set_keepalive, + .o_get = tcp_get_keepalive, + .o_set = tcp_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) +static int +tcp_getx(void *arg, const char *name, void *buf, size_t *szp, nni_type t) { - return (nni_getopt(tcp_conn_options, name, c, buf, szp, t)); + nni_tcp_conn *c = arg; + return (nni_getopt(tcp_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) +static int +tcp_setx(void *arg, const char *name, const void *buf, size_t sz, nni_type t) { - return (nni_setopt(tcp_conn_options, name, c, buf, sz, t)); + nni_tcp_conn *c = arg; + return (nni_setopt(tcp_options, name, c, buf, sz, t)); } -void -nni_tcp_conn_fini(nni_tcp_conn *c) +static void +tcp_free(void *arg) { - nni_tcp_conn_close(c); + nni_tcp_conn *c = arg; + tcp_close(c); nni_mtx_lock(&c->mtx); while ((!nni_list_empty(&c->recv_aios)) || @@ -502,3 +423,49 @@ nni_tcp_conn_fini(nni_tcp_conn *c) nni_mtx_fini(&c->mtx); NNI_FREE_STRUCT(c); } + +int +nni_win_tcp_conn_init(nni_tcp_conn **connp, SOCKET s) +{ + nni_tcp_conn *c; + int rv; + BOOL yes; + DWORD no; + + // Don't inherit the handle (CLOEXEC really). + SetHandleInformation((HANDLE) s, HANDLE_FLAG_INHERIT, 0); + + if ((c = NNI_ALLOC_STRUCT(c)) == NULL) { + return (NNG_ENOMEM); + } + c->s = INVALID_SOCKET; + nni_mtx_init(&c->mtx); + nni_cv_init(&c->cv, &c->mtx); + nni_aio_list_init(&c->recv_aios); + nni_aio_list_init(&c->send_aios); + c->conn_aio = NULL; + c->ops.s_close = tcp_close; + c->ops.s_free = tcp_free; + c->ops.s_send = tcp_send; + c->ops.s_recv = tcp_recv; + c->ops.s_getx = tcp_getx; + c->ops.s_setx = tcp_setx; + + if (((rv = nni_win_io_init(&c->recv_io, tcp_recv_cb, c)) != 0) || + ((rv = nni_win_io_init(&c->send_io, tcp_send_cb, c)) != 0) || + ((rv = nni_win_io_register((HANDLE) s)) != 0)) { + tcp_free(c); + return (rv); + } + + no = 0; + (void) setsockopt( + s, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &no, sizeof(no)); + yes = 1; + (void) setsockopt( + s, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, sizeof(yes)); + + c->s = s; + *connp = c; + return (0); +} diff --git a/src/platform/windows/win_tcpdial.c b/src/platform/windows/win_tcpdial.c index 64b4e800..6bb3d92a 100644 --- a/src/platform/windows/win_tcpdial.c +++ b/src/platform/windows/win_tcpdial.c @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. +// Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // Copyright 2018 Devolutions // @@ -16,6 +16,18 @@ #include #include +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; // source address + size_t srclen; + nni_mtx mtx; + nni_reap_item reap; +}; + int nni_tcp_dialer_init(nni_tcp_dialer **dp) { @@ -137,7 +149,7 @@ tcp_dial_cb(nni_win_io *io, int rv, size_t cnt) nni_mtx_unlock(&d->mtx); if (rv != 0) { - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); } else { DWORD yes = 1; @@ -156,19 +168,22 @@ tcp_dial_cb(nni_win_io *io, int rv, size_t cnt) } void -nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) +nni_tcp_dial(nni_tcp_dialer *d, nni_aio *aio) { SOCKET s; SOCKADDR_STORAGE ss; int len; nni_tcp_conn * c; int rv; + nng_sockaddr sa; + + nni_aio_get_sockaddr(aio, &sa); if (nni_aio_begin(aio) != 0) { return; } - if ((len = nni_win_nn2sockaddr(&ss, sa)) <= 0) { + if ((len = nni_win_nn2sockaddr(&ss, &sa)) <= 0) { nni_aio_finish_error(aio, NNG_EADDRINVAL); return; } @@ -179,7 +194,7 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) } if ((rv = nni_win_tcp_conn_init(&c, s)) != 0) { - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } @@ -194,7 +209,7 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) nni_mtx_lock(&d->mtx); if (d->closed) { nni_mtx_unlock(&d->mtx); - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, NNG_ECLOSED); return; } @@ -212,7 +227,7 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) if (bind(s, (SOCKADDR *) &c->sockname, len) != 0) { rv = nni_win_error(GetLastError()); nni_mtx_unlock(&d->mtx); - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } @@ -221,7 +236,7 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) nni_aio_set_prov_extra(aio, 0, c); if ((rv = nni_aio_schedule(aio, tcp_dial_cancel, d)) != 0) { nni_mtx_unlock(&d->mtx); - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } @@ -234,8 +249,7 @@ nni_tcp_dialer_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio) if ((rv = GetLastError()) != ERROR_IO_PENDING) { nni_aio_list_remove(aio); nni_mtx_unlock(&d->mtx); - - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } diff --git a/src/platform/windows/win_tcplisten.c b/src/platform/windows/win_tcplisten.c index 9cf16985..e98a0c37 100644 --- a/src/platform/windows/win_tcplisten.c +++ b/src/platform/windows/win_tcplisten.c @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. +// Copyright 2019 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // Copyright 2018 Devolutions // @@ -98,7 +98,7 @@ tcp_accept_cb(nni_win_io *io, int rv, size_t cnt) nni_mtx_unlock(&l->mtx); if (rv != 0) { - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } @@ -309,7 +309,7 @@ nni_tcp_listener_accept(nni_tcp_listener *l, nni_aio *aio) ((rv = nni_aio_schedule(aio, tcp_accept_cancel, l)) != 0)) { nni_aio_set_prov_extra(aio, 0, NULL); nni_mtx_unlock(&l->mtx); - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } @@ -320,7 +320,7 @@ nni_tcp_listener_accept(nni_tcp_listener *l, nni_aio *aio) // Fast failure (synchronous.) nni_aio_list_remove(aio); nni_mtx_unlock(&l->mtx); - nni_tcp_conn_fini(c); + nng_stream_free(&c->ops); nni_aio_finish_error(aio, rv); return; } -- cgit v1.2.3-70-g09d2