From ee16d11a59120cd4d981e0dcb90741fa4141372a Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sat, 22 Dec 2018 19:23:26 -0800 Subject: fixes #823 Define public IPC (#824) This introduces a basic IPC API, modeled on the TCP API, for direct access. Only connection options are exposed at present -- we need to add options for dialers and listeners (and particularly listener settings for permissions and security attributes.) Documentation is still outstanding, but a very limited test suite exists. --- include/nng/supplemental/ipc/ipc.h | 133 +++++++++++++++++++++++++++++++++++++ include/nng/supplemental/tcp/tcp.h | 9 ++- 2 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 include/nng/supplemental/ipc/ipc.h (limited to 'include') diff --git a/include/nng/supplemental/ipc/ipc.h b/include/nng/supplemental/ipc/ipc.h new file mode 100644 index 00000000..f7091ec8 --- /dev/null +++ b/include/nng/supplemental/ipc/ipc.h @@ -0,0 +1,133 @@ +// +// Copyright 2018 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV +// Copyright 2018 Devolutions +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#ifndef NNG_SUPPLEMENTAL_IPC_IPC_H +#define NNG_SUPPLEMENTAL_IPC_IPC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include // For IPC option names. + +// This is our "public" IPC API. This allows applications to access +// basic IPC functions, using our AIO framework. Most applications will +// not need this. This supports both UNIX domain sockets (AF_LOCAL), +// and Windows Named Pipes, depending on the underlying platform. + +// nng_ipc represents a single IPC connection. This is generally +// a connected stream. +typedef struct nng_ipc_s nng_ipc; + +// nng_ipc_dialer is a dialer object used to create outgoing connections. +// This is a bit different than a typical BSD socket API, but doing it +// helps keep the API orthogonal to the listener API. +typedef struct nng_ipc_dialer_s nng_ipc_dialer; + +// nng_ipc_listener is a listener object. This is used to accept incoming +// connections. +typedef struct nng_ipc_listener_s nng_ipc_listener; + +// nng_ipc_close closes the connection, but does not release the +// underlying object. Operations that may be pending on the connect, +// as well as further operations, will result in NNG_ECLOSED. +NNG_DECL void nng_ipc_close(nng_ipc *); + +// nng_ipc_free frees the IPC connection, closing it if it is open. +// This is necessary to release the resources of the IPC object. +// (It is an error to refer to the IPC object after this is called.) +NNG_DECL void nng_ipc_free(nng_ipc *); + +// nng_ipc_send sends the data in the aio, which should be stored in +// an iov for the message. Note that the iov in the aio may be modified, +// so applications should not assume otherwise. +NNG_DECL void nng_ipc_send(nng_ipc *, nng_aio *); + +// nng_ipc_recv receives data into the iov supplied. It is possible for +// the callback to be executed with less data read than requested. (This +// is actually pretty likely for bulk transfers.) The caller should update +// the iov's and resubmit as needed. +NNG_DECL void nng_ipc_recv(nng_ipc *, nng_aio *); + +// nng_ipc_getopt is used to get options. The options available are: +// +// NNG_OPT_REMADDR - nng_sockaddr for the connection. +// NNG_OPT_LOCADD - nng_sockaddr for the connection. +// NNG_OPT_IPC_PEER_UID - peer user ID (if available), uint64_t +// NNG_OPT_IPC_PEER_GID - peer group ID (if available), uint64_t +// NNG_OPT_IPC_PEER_ZONEID - peer zone ID (illumos/Solaris only), uint64_t +NNG_DECL int nng_ipc_getopt(nng_ipc *, const char *, void *, size_t *); + +// nng_ipc_setopt is used to set options. There are presently no such +// options defined for connections. +NNG_DECL int nng_ipc_setopt(nng_ipc *, const char *, const void *, size_t); + +// nng_ipc_dialer_alloc is used to allocate an IPC dialer. +NNG_DECL int nng_ipc_dialer_alloc(nng_ipc_dialer **); + +// nng_ipc_dialer_close closes the dialer, aborting any pending outbound +// connection attempts (and preventing any new ones) with NNG_ECLOSED. +// This does not free the resources associated with the dialer, so the +// application should still call nng_ipc_dialer_free. Connections already +// established by the dialer are unaffected by this call. +NNG_DECL void nng_ipc_dialer_close(nng_ipc_dialer *); + +// nng_ipc_dialer_free is used to free the dialer. This implicitly calls +// nng_ipc_dialer_close, then releases the resources associated with the +// dialer. It is therefore an error for the application to attempt to use +// the dialer after this call. +NNG_DECL void nng_ipc_dialer_free(nng_ipc_dialer *); + +// nng_ipc_dialer_dial attempts to create a new connection (nng_ipc *) +// may making an outbound connect call. If this succeeds, the aio +// will return a suitable nng_ipc * in the first output of the aio. +// (I.e. nng_aio_get_output(aio, 0).) The destination address to dial +// is stored in the 2nd argument. +NNG_DECL void nng_ipc_dialer_dial( + nng_ipc_dialer *, const nng_sockaddr *, nng_aio *); + +// nng_ipc_listener_alloc creates a listener. +NNG_DECL int nng_ipc_listener_alloc(nng_ipc_listener **); + +// nng_ipc_listener_close closes the listener, unbinding it from +// any active path if it was previously bound with nng_ipc_listener_listen. +// This does not completely release the resources associated with the +// listener, so nng_ipc_listener_free should still be called. +// Any pending accept calls will be aborted with NNG_ECLOSED, and any +// future attempts will also result in NNG_ECLOSED. Connections already +// established by this listener are unaffected by this call. +NNG_DECL void nng_ipc_listener_close(nng_ipc_listener *); + +// nng_ipc_listener_free frees the listener. This causes any other +// outstanding accept calls to return NNG_ECLOSED. The listener cannot +// be used by the application after this is called. This implictly +// includes a call to nng_ipc_listener_close(). +NNG_DECL void nng_ipc_listener_free(nng_ipc_listener *); + +// nng_ipc_listener_listen binds to the IPC address and arranges for +// the IPC path to be created and bound. It does not accept any new +// incoming connections. This operation is synchronous. +NNG_DECL int nng_ipc_listener_listen(nng_ipc_listener *, const nng_sockaddr *); + +// nng_ipc_listener_accept accepts an incoming connection (creating an +// nng_ipc * object), and returns it in the nng_aio as the first output +// on success. +NNG_DECL void nng_ipc_listener_accept(nng_ipc_listener *, nng_aio *); + +#ifdef __cplusplus +} +#endif + +#endif // NNG_SUPPLEMENTAL_IPC_IPC_H diff --git a/include/nng/supplemental/tcp/tcp.h b/include/nng/supplemental/tcp/tcp.h index 992bfd81..9b83d678 100644 --- a/include/nng/supplemental/tcp/tcp.h +++ b/include/nng/supplemental/tcp/tcp.h @@ -37,8 +37,8 @@ typedef struct nng_tcp_dialer_s nng_tcp_dialer; // connections. typedef struct nng_tcp_listener_s nng_tcp_listener; -// nng_tcp_conn close closes the connection, but does not release -// the underlying object. Operations that may be pending on the connect, +// nng_tcp_close closes the connection, but does not release the +// underlying object. Operations that may be pending on the connect, // as well as further operations, will result in NNG_ECLOSED. NNG_DECL void nng_tcp_close(nng_tcp *); @@ -47,7 +47,7 @@ NNG_DECL void nng_tcp_close(nng_tcp *); // (It is an error to refer to the TCP object after this is called.) NNG_DECL void nng_tcp_free(nng_tcp *); -// nng_tcp_conn_send sends the data in the aio, which should be stored in +// nng_tcp_send sends the data in the aio, which should be stored in // an iov for the message. Note that the iov in the aio may be modified, // so applications should not assume otherwise. NNG_DECL void nng_tcp_send(nng_tcp *, nng_aio *); @@ -58,8 +58,7 @@ NNG_DECL void nng_tcp_send(nng_tcp *, nng_aio *); // the iov's and resubmit as needed. NNG_DECL void nng_tcp_recv(nng_tcp *, nng_aio *); -// nng_tcp_sockname obtains an nng_sockaddr associated with our local -// address. +// nng_tcp_sockname obtains an nng_sockaddr associated with our local address. NNG_DECL int nng_tcp_sockname(nng_tcp *, nng_sockaddr *); // nng_tcp_peername obtains an nng_sockaddr associated with our peer. -- cgit v1.2.3-70-g09d2