From c457bddfae64521ea9861f2211e6cb25858559b3 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Fri, 23 Feb 2018 14:48:46 -0800 Subject: Move compatibility header so that works. Basically, we have moved the compat stuff into a separate directory. Compatibility layer users will have to update their compile flags, but should be able to avoid changing any *source* files with this change. --- src/CMakeLists.txt | 5 +- src/compat/nanomsg/CMakeLists.txt | 15 + src/compat/nanomsg/nn.c | 728 ++++++++++++++++++++++++++++++++++++++ src/compat/nanomsg/nn.h | 315 +++++++++++++++++ src/nng_compat.c | 728 -------------------------------------- src/nng_compat.h | 315 ----------------- tests/CMakeLists.txt | 15 +- tests/compat_block.c | 2 +- tests/compat_bug777.c | 7 +- tests/compat_bus.c | 2 +- tests/compat_cmsg.c | 4 +- tests/compat_device.c | 2 +- tests/compat_iovec.c | 2 +- tests/compat_msg.c | 2 +- tests/compat_pair.c | 2 +- tests/compat_pipeline.c | 2 +- tests/compat_reqrep.c | 6 +- tests/compat_reqttl.c | 4 +- tests/compat_shutdown.c | 2 +- tests/compat_survey.c | 2 +- tests/compat_testutil.c | 4 +- 21 files changed, 1085 insertions(+), 1079 deletions(-) create mode 100644 src/compat/nanomsg/CMakeLists.txt create mode 100644 src/compat/nanomsg/nn.c create mode 100644 src/compat/nanomsg/nn.h delete mode 100644 src/nng_compat.c delete mode 100644 src/nng_compat.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2cf03e45..52f4f354 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,9 +28,6 @@ set (NNG_SOURCES nng.c nng.h - nng_compat.c - nng_compat.h - core/defs.h core/aio.c @@ -128,6 +125,8 @@ endif() set (NNG_HEADERS nng.h) +add_subdirectory(compat/nanomsg) + add_subdirectory(supplemental/base64) add_subdirectory(supplemental/http) add_subdirectory(supplemental/sha1) diff --git a/src/compat/nanomsg/CMakeLists.txt b/src/compat/nanomsg/CMakeLists.txt new file mode 100644 index 00000000..d1a692b7 --- /dev/null +++ b/src/compat/nanomsg/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright 2018 Capitar IT Group BV +# Copyright 2018 Staysail Systems, Inc. +# +# 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. +# + +set(COMPAT_SOURCES compat/nanomsg/nn.c) +set(COMPAT_HEADERS compat/nanomsg/nn.h) + +set(NNG_SOURCES ${NNG_SOURCES} ${COMPAT_SOURCES} PARENT_SCOPE) +set(NNG_HEADERS ${NNG_HEADERS} ${COMPAT_HEADERS} PARENT_SCOPE) diff --git a/src/compat/nanomsg/nn.c b/src/compat/nanomsg/nn.c new file mode 100644 index 00000000..1d5bcfbb --- /dev/null +++ b/src/compat/nanomsg/nn.c @@ -0,0 +1,728 @@ +// +// Copyright 2018 Garrett D'Amore +// Copyright 2018 Capitar IT Group BV +// +// 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. +// + +#include "nn.h" +#include "nng.h" +#include "protocol/bus0/bus.h" +#include "protocol/pair0/pair.h" +#include "protocol/pipeline0/pull.h" +#include "protocol/pipeline0/push.h" +#include "protocol/pubsub0/pub.h" +#include "protocol/pubsub0/sub.h" +#include "protocol/reqrep0/rep.h" +#include "protocol/reqrep0/req.h" +#include "protocol/survey0/respond.h" +#include "protocol/survey0/survey.h" + +#include +#include + +// This file supplies the legacy compatibility API. Applications should +// avoid using these if at all possible, and instead use the new style APIs. + +static const struct { + int nerr; + int perr; +} nn_errnos[] = { + // clang-format off + { NNG_EINTR, EINTR }, + { NNG_ENOMEM, ENOMEM }, + { NNG_EINVAL, EINVAL }, + { NNG_EBUSY, EBUSY }, + { NNG_ETIMEDOUT, ETIMEDOUT }, + { NNG_ECONNREFUSED, ECONNREFUSED }, + { NNG_ECLOSED, EBADF }, + { NNG_EAGAIN, EAGAIN }, + { NNG_ENOTSUP, ENOTSUP }, + { NNG_EADDRINUSE, EADDRINUSE }, + { NNG_ESTATE, EFSM }, + { NNG_ENOENT, ENOENT }, + { NNG_EPROTO, EPROTO }, + { NNG_EUNREACHABLE, EHOSTUNREACH }, + { NNG_EADDRINVAL, EADDRNOTAVAIL }, + { NNG_EPERM, EACCES }, + { NNG_EMSGSIZE, EMSGSIZE }, + { NNG_ECONNABORTED, ECONNABORTED }, + { NNG_ECONNRESET, ECONNRESET }, + { NNG_ECANCELED, EBADF }, + { 0, 0 }, + // clang-format on +}; + +const char * +nn_strerror(int err) +{ + int i; + static char msgbuf[32]; + + for (i = 0; nn_errnos[i].perr != 0; i++) { + if (nn_errnos[i].perr == err) { + return (nng_strerror(nn_errnos[i].nerr)); + } + } + if (err == EIO) { + return ("Unknown I/O error"); + } + + // Arguably we could use strerror() here, but we should only + // be getting errnos we understand at this point. + (void) snprintf(msgbuf, sizeof(msgbuf), "Unknown error %d", err); + return (msgbuf); +} + +static void +nn_seterror(int err) +{ + int i; + + for (i = 0; nn_errnos[i].nerr != 0; i++) { + if (nn_errnos[i].nerr == err) { + errno = nn_errnos[i].perr; + return; + } + } + // No idea... + errno = EIO; +} + +int +nn_errno(void) +{ + return (errno); +} + +static const struct { + uint16_t p_id; + int (*p_open)(nng_socket *); +} nn_protocols[] = { +// clang-format off +#ifdef NNG_HAVE_BUS0 + { NN_BUS, nng_bus0_open }, +#endif +#ifdef NNG_HAVE_PAIR0 + { NN_PAIR, nng_pair0_open }, +#endif +#ifdef NNG_HAVE_PUSH0 + { NN_PUSH, nng_push0_open }, +#endif +#ifdef NNG_HAVE_PULL0 + { NN_PULL, nng_pull0_open }, +#endif +#ifdef NNG_HAVE_PUB0 + { NN_PUB, nng_pub0_open }, +#endif +#ifdef NNG_HAVE_SUB0 + { NN_SUB, nng_sub0_open }, +#endif +#ifdef NNG_HAVE_REQ0 + { NN_REQ, nng_req0_open }, +#endif +#ifdef NNG_HAVE_REP0 + { NN_REP, nng_rep0_open }, +#endif +#ifdef NNG_HAVE_SURVEYOR0 + { NN_SURVEYOR, nng_surveyor0_open }, +#endif +#ifdef NNG_HAVE_RESPONDENT0 + { NN_RESPONDENT, nng_respondent0_open }, +#endif + { 0, NULL }, + // clang-format on +}; + +int +nn_socket(int domain, int protocol) +{ + nng_socket sock; + int rv; + int i; + + if ((domain != AF_SP) && (domain != AF_SP_RAW)) { + errno = EAFNOSUPPORT; + return (-1); + } + + for (i = 0; nn_protocols[i].p_id != 0; i++) { + if (nn_protocols[i].p_id == protocol) { + break; + } + } + if (nn_protocols[i].p_open == NULL) { + errno = ENOTSUP; + return (-1); + } + + if ((rv = nn_protocols[i].p_open(&sock)) != 0) { + nn_seterror(rv); + return (-1); + } + if (domain == AF_SP_RAW) { + if ((rv = nng_setopt_int(sock, NNG_OPT_RAW, 1)) != 0) { + nn_seterror(rv); + nng_close(sock); + return (-1); + } + } + return ((int) sock); +} + +int +nn_close(int s) +{ + int rv; + + if ((rv = nng_close((nng_socket) s)) != 0) { + nn_seterror(rv); + return (-1); + } + return (0); +} + +int +nn_bind(int s, const char *addr) +{ + int rv; + nng_listener l; + + if ((rv = nng_listen((nng_socket) s, addr, &l, 0)) != 0) { + nn_seterror(rv); + return (-1); + } + return ((int) l); +} + +int +nn_connect(int s, const char *addr) +{ + int rv; + nng_dialer d; + + if ((rv = nng_dial((nng_socket) s, addr, &d, NNG_FLAG_NONBLOCK)) != + 0) { + nn_seterror(rv); + return (-1); + } + return ((int) d); +} + +int +nn_shutdown(int s, int ep) +{ + int rv; + (void) s; // Unused + + // Socket is wired into the endpoint... so passing a bad endpoint + // ID can result in affecting the wrong socket. But this requires + // a buggy application, and because we don't recycle endpoints + // until wrap, its unlikely to actually come up in practice. + // Note that listeners and dialers share the same namespace + // in the core, so we can close either one this way. + + if (((rv = nng_dialer_close((nng_dialer) ep)) != 0) && + ((rv = nng_listener_close((nng_listener) ep)) != 0)) { + nn_seterror(rv); + return (-1); + } + return (0); +} + +void * +nn_allocmsg(size_t size, int type) +{ + nng_msg *msg; + int rv; + + // Validate type and non-zero size. This also checks for overflow. + if ((type != 0) || (size < 1) || ((size + sizeof(msg) < size))) { + nn_seterror(NNG_EINVAL); + return (NULL); + } + + // So our "messages" from nn are really going to be nng messages + // but to make this work, we use a bit of headroom in the message + // to stash the message header. + if ((rv = nng_msg_alloc(&msg, size + (sizeof(msg)))) != 0) { + nn_seterror(rv); + return (NULL); + } + + // This counts on message bodies being aligned sensibly. + *(nng_msg **) (nng_msg_body(msg)) = msg; + + // We are counting on the implementation of nn_msg_trim to not + // reallocate the message but just to leave the prefix inplace. + (void) nng_msg_trim(msg, sizeof(msg)); + + return (nng_msg_body(msg)); +} + +int +nn_freemsg(void *ptr) +{ + nng_msg *msg; + + msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); + nng_msg_free(msg); + return (0); +} + +void * +nn_reallocmsg(void *ptr, size_t len) +{ + nng_msg *msg; + int rv; + + if ((len + sizeof(msg)) < len) { + // overflowed! + nn_seterror(NNG_EINVAL); + return (NULL); + } + + // This counts on message bodies being aligned sensibly. + msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); + + // We need to realloc the requested len, plus size for our header. + if ((rv = nng_msg_realloc(msg, len + sizeof(msg))) != 0) { + // We don't free the old message. Code is free to cope + // as it sees fit. + nn_seterror(rv); + return (NULL); + } + // Stash the msg header pointer + *(nng_msg **) (nng_msg_body(msg)) = msg; + nng_msg_trim(msg, sizeof(msg)); + return (nng_msg_body(msg)); +} + +static int +nn_flags(int flags) +{ + switch (flags) { + case 0: + return (0); + + case NN_DONTWAIT: + return (NNG_FLAG_NONBLOCK); + + default: + nn_seterror(NNG_EINVAL); + return (-1); + } +} + +int +nn_send(int s, const void *buf, size_t len, int flags) +{ + struct nn_iovec iov; + struct nn_msghdr hdr; + + iov.iov_base = (void *) buf; + iov.iov_len = len; + + hdr.msg_iov = &iov; + hdr.msg_iovlen = 1; + hdr.msg_control = NULL; + hdr.msg_controllen = 0; + + return (nn_sendmsg(s, &hdr, flags)); +} + +int +nn_recv(int s, void *buf, size_t len, int flags) +{ + struct nn_iovec iov; + struct nn_msghdr hdr; + + iov.iov_base = buf; + iov.iov_len = len; + + hdr.msg_iov = &iov; + hdr.msg_iovlen = 1; + hdr.msg_control = NULL; + hdr.msg_controllen = 0; + + return (nn_recvmsg(s, &hdr, flags)); +} + +int +nn_recvmsg(int s, struct nn_msghdr *mh, int flags) +{ + int rv; + nng_msg *msg; + size_t len; + int keep = 0; + + if ((flags = nn_flags(flags)) == -1) { + return (-1); + } + if (mh == NULL) { + nn_seterror(NNG_EINVAL); + return (-1); + } + if (mh->msg_iovlen < 0) { + nn_seterror(NNG_EMSGSIZE); + return (-1); + } + + if ((rv = nng_recvmsg((nng_socket) s, &msg, flags)) != 0) { + nn_seterror(rv); + return (-1); + } + if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { + // Receiver wants to have a dynamically allocated message. + // There can only be one of these. + if ((rv = nng_msg_insert(msg, &msg, sizeof(msg))) != 0) { + nng_msg_free(msg); + nn_seterror(rv); + return (-1); + } + nng_msg_trim(msg, sizeof(msg)); + *(void **) (mh->msg_iov[0].iov_base) = nng_msg_body(msg); + len = nng_msg_len(msg); + keep = 1; // Do not discard message! + } else { + // copyout to multiple iovecs. + char * ptr = nng_msg_body(msg); + int i; + size_t n; + len = nng_msg_len(msg); + + for (i = 0; i < mh->msg_iovlen; i++) { + if ((n = mh->msg_iov[i].iov_len) == NN_MSG) { + // This is forbidden! + nn_seterror(NNG_EINVAL); + nng_msg_free(msg); + return (-1); + } + if (n > len) { + n = len; + } + memcpy(mh->msg_iov[i].iov_base, ptr, n); + len -= n; + ptr += n; + } + + // If we copied everything, len will be zero, otherwise, + // it represents the amount of data that we were unable to + // copyout. The caller is responsible for noticing this, + // as there is no API to pass this information out. + len = nng_msg_len(msg); + } + + // If the caller has requested control information (header details), + // we grab it. + if (mh->msg_control != NULL) { + char * cdata; + size_t clen; + size_t tlen; + size_t spsz; + struct nn_cmsghdr *hdr; + unsigned char * ptr; + + spsz = nng_msg_header_len(msg); + clen = NN_CMSG_SPACE(sizeof(spsz) + spsz); + + if ((tlen = mh->msg_controllen) == NN_MSG) { + // Ideally we'd use the same msg, but we would need + // to set up reference counts on the message, so + // instead we just make a new message. + nng_msg *nmsg; + + rv = nng_msg_alloc(&nmsg, clen + sizeof(nmsg)); + if (rv != 0) { + nng_msg_free(msg); + nn_seterror(rv); + return (-1); + } + memcpy(nng_msg_body(nmsg), &nmsg, sizeof(nmsg)); + nng_msg_trim(nmsg, sizeof(nmsg)); + cdata = nng_msg_body(nmsg); + *(void **) mh->msg_control = cdata; + tlen = clen; + } else { + cdata = mh->msg_control; + memset(cdata, 0, + tlen > sizeof(*hdr) ? sizeof(*hdr) : tlen); + } + + if (clen <= tlen) { + ptr = NN_CMSG_DATA(cdata); + hdr = (void *) cdata; + hdr->cmsg_len = clen; + hdr->cmsg_level = PROTO_SP; + hdr->cmsg_type = SP_HDR; + + memcpy(ptr, &spsz, sizeof(spsz)); + ptr += sizeof(spsz); + memcpy(ptr, nng_msg_header(msg), spsz); + } + } + + if (!keep) { + nng_msg_free(msg); + } + return ((int) len); +} + +int +nn_sendmsg(int s, const struct nn_msghdr *mh, int flags) +{ + nng_msg *msg = NULL; + nng_msg *cmsg = NULL; + char * cdata; + int keep = 0; + size_t sz; + int rv; + + if ((flags = nn_flags(flags)) == -1) { + return (-1); + } + + if (mh == NULL) { + nn_seterror(NNG_EINVAL); + return (-1); + } + + if (mh->msg_iovlen < 0) { + nn_seterror(NNG_EMSGSIZE); + return (-1); + } + + if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { + char *bufp = *(char **) (mh->msg_iov[0].iov_base); + + msg = *(nng_msg **) (bufp - sizeof(msg)); + keep = 1; // keep the message on error + } else { + char *ptr; + int i; + + sz = 0; + // Get the total message size. + for (i = 0; i < mh->msg_iovlen; i++) { + sz += mh->msg_iov[i].iov_len; + } + if ((rv = nng_msg_alloc(&msg, sz)) != 0) { + nn_seterror(rv); + return (-1); + } + // Now copy it out. + ptr = nng_msg_body(msg); + for (i = 0; i < mh->msg_iovlen; i++) { + memcpy(ptr, mh->msg_iov[i].iov_base, + mh->msg_iov[i].iov_len); + ptr += mh->msg_iov[i].iov_len; + } + } + + // Now suck up the control data... + // This POSIX-inspired API is one of the most painful for + // usability we've ever seen. + cmsg = NULL; + if ((cdata = mh->msg_control) != NULL) { + size_t clen; + size_t offs; + size_t spsz; + struct nn_cmsghdr *chdr; + unsigned char * data; + + if ((clen = mh->msg_controllen) == NN_MSG) { + // Underlying data is a message. This is awkward, + // because we have to copy the data, but we should + // only free this message on success. So we save the + // message now. + cdata = *(void **) cdata; + cmsg = *(nng_msg **) (cdata - sizeof(cmsg)); + clen = nng_msg_len(cmsg); + } else { + clen = mh->msg_controllen; + } + + offs = 0; + while ((offs + sizeof(NN_CMSG_LEN(0))) < clen) { + chdr = (void *) (cdata + offs); + if ((chdr->cmsg_level != PROTO_SP) || + (chdr->cmsg_type != SP_HDR)) { + offs += chdr->cmsg_len; + } + + // SP header in theory. Starts with size, then + // any backtrace details. + if (chdr->cmsg_len < sizeof(size_t)) { + offs += chdr->cmsg_len; + continue; + } + data = NN_CMSG_DATA(chdr); + memcpy(&spsz, data, sizeof(spsz)); + if ((spsz + sizeof(spsz)) > chdr->cmsg_len) { + // Truncated header? Ignore it. + offs += chdr->cmsg_len; + continue; + } + data += sizeof(spsz); + rv = nng_msg_header_append(msg, data, spsz); + if (rv != 0) { + if (!keep) { + nng_msg_free(msg); + } + nn_seterror(rv); + return (-1); + } + + break; + } + } + + sz = nng_msg_len(msg); + if ((rv = nng_sendmsg((nng_socket) s, msg, flags)) != 0) { + if (!keep) { + nng_msg_free(msg); + } + nn_seterror(rv); + return (-1); + } + + if (cmsg != NULL) { + // We sent successfully, so free up the control message. + nng_msg_free(cmsg); + } + return ((int) sz); +} + +// options which we convert -- most of the array is initialized at run time. +static const struct { + int nnlevel; + int nnopt; + const char *opt; +} options[] = { + { NN_SOL_SOCKET, NN_LINGER, NNG_OPT_LINGER }, // review + { NN_SOL_SOCKET, NN_SNDBUF, NNG_OPT_SENDBUF }, + { NN_SOL_SOCKET, NN_RCVBUF, NNG_OPT_RECVBUF }, + { NN_SOL_SOCKET, NN_RECONNECT_IVL, NNG_OPT_RECONNMINT }, + { NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, NNG_OPT_RECONNMAXT }, + { NN_SOL_SOCKET, NN_SNDFD, NNG_OPT_SENDFD }, + { NN_SOL_SOCKET, NN_RCVFD, NNG_OPT_RECVFD }, + { NN_SOL_SOCKET, NN_RCVMAXSIZE, NNG_OPT_RECVMAXSZ }, + { NN_SOL_SOCKET, NN_MAXTTL, NNG_OPT_MAXTTL }, + { NN_SOL_SOCKET, NN_RCVTIMEO, NNG_OPT_RECVTIMEO }, + { NN_SOL_SOCKET, NN_SNDTIMEO, NNG_OPT_SENDTIMEO }, + { NN_SOL_SOCKET, NN_DOMAIN, NNG_OPT_DOMAIN }, + { NN_SOL_SOCKET, NN_SOCKET_NAME, NNG_OPT_SOCKNAME }, + { NN_REQ, NN_REQ_RESEND_IVL, NNG_OPT_REQ_RESENDTIME }, + { NN_SUB, NN_SUB_SUBSCRIBE, NNG_OPT_SUB_SUBSCRIBE }, + { NN_SUB, NN_SUB_UNSUBSCRIBE, NNG_OPT_SUB_UNSUBSCRIBE }, + { NN_SURVEYOR, NN_SURVEYOR_DEADLINE, NNG_OPT_SURVEYOR_SURVEYTIME }, + // XXX: IPV4ONLY, SNDPRIO, RCVPRIO +}; + +int +nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) +{ + const char *name = NULL; + int rv; + + for (unsigned i = 0; i < sizeof(options) / sizeof(options[0]); i++) { + if ((options[i].nnlevel == nnlevel) && + (options[i].nnopt == nnopt)) { + name = options[i].opt; + break; + } + } + + if (name == NULL) { + errno = ENOPROTOOPT; + return (-1); + } + + if ((rv = nng_getopt((nng_socket) s, name, valp, szp)) != 0) { + nn_seterror(rv); + return (-1); + } + + return (0); +} + +int +nn_setsockopt(int s, int nnlevel, int nnopt, const void *valp, size_t sz) +{ + const char *name = NULL; + int rv; + + for (unsigned i = 0; i < sizeof(options) / sizeof(options[0]); i++) { + if ((options[i].nnlevel == nnlevel) && + (options[i].nnopt == nnopt)) { + name = options[i].opt; + break; + } + } + if (name == NULL) { + return (ENOPROTOOPT); + } + + if ((rv = nng_setopt((nng_socket) s, name, valp, sz)) != 0) { + nn_seterror(rv); + return (-1); + } + return (0); +} + +struct nn_cmsghdr * +nn_cmsg_next(struct nn_msghdr *mh, struct nn_cmsghdr *first) +{ + size_t clen; + char * data; + + // We only support SP headers, so there can be at most one header. + if (first != NULL) { + return (NULL); + } + if ((clen = mh->msg_controllen) == NN_MSG) { + nng_msg *msg; + data = *((void **) (mh->msg_control)); + msg = *(nng_msg **) (data - sizeof(msg)); + clen = nng_msg_len(msg); + } else { + data = mh->msg_control; + } + + if (first == NULL) { + first = (void *) data; + } else { + first = first + first->cmsg_len; + } + + if (((char *) first + sizeof(*first)) > (data + clen)) { + return (NULL); + } + return (first); +} + +int +nn_device(int s1, int s2) +{ + int rv; + + rv = nng_device((nng_socket) s1, (nng_socket) s2); + // rv must always be nonzero + nn_seterror(rv); + return (-1); +} + +// nn_term is suitable only for shutting down the entire library, +// and is not thread-safe with other functions. +void +nn_term(void) +{ + // This function is relatively toxic, since it can affect + // all sockets in the process, including those + // in use by libraries, etc. Accordingly, do not use this + // in a library -- only e.g. atexit() and similar. + nng_closeall(); +} diff --git a/src/compat/nanomsg/nn.h b/src/compat/nanomsg/nn.h new file mode 100644 index 00000000..8c5cee6f --- /dev/null +++ b/src/compat/nanomsg/nn.h @@ -0,0 +1,315 @@ +// +// Copyright 2017 Garrett D'Amore +// Copyright 2017 Capitar IT Group BV +// +// 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_COMPAT_H +#define NNG_COMPAT_H + +// This header contains interfaces that are intended to offer compatibility +// with nanomsg v1.0. These are not the "preferred" interfaces for nng, +// and consumers should only use thse if they are porting software that +// previously used nanomsg. New programs should use the nng native APIs. + +// Note that compatibility promises are limited to public portions of the +// nanomsg API, and specifically do NOT extend to the ABI. Furthermore, +// there may be other limitations around less commonly used portions of the +// API; for example only SP headers may be transported in control data for +// messages, there is almost no compatibility offered for statistics. +// Error values may differ from those returned by nanomsg as well; the nng +// error reporting facility expresses only a subset of the possibilities of +// nanomsg. + +// Note that unlinke nanomsg, nng does not aggressively recycle socket or +// endpoint IDs, which means applications which made assumptions that these +// would be relatively small integers (e.g. to use them as array indices) +// may break. (No promise about values was ever made.) + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +// clang-format gets in the way of most of this file. +// We turn it off, at least until it gets smarter about aligning +// macro definitions or we adopt enums or somesuch. +// clang-format off + +// NNG_DECL is used on declarations to deal with scope. +// For building Windows DLLs, it should be the appropriate +// __declspec(). (We recommend *not* building this library +// as a DLL, but instead linking it statically for your projects +// to minimize questions about link dependencies later.) +#ifndef NN_DECL +#if defined(_WIN32) && !defined(NNG_STATIC_LIB) +#if defined(NNG_SHARED_LIB) +#define NN_DECL __declspec(dllexport) +#else +#define NN_DECL __declspec(dllimport) +#endif // NNG_SHARED_LIB +#else +#define NN_DECL extern +#endif // _WIN32 && !NNG_STATIC_LIB +#endif // NN_DECL + +#define AF_SP 1 +#define AF_SP_RAW 2 + +// Protocol stuff +#define NN_PROTO_PAIR 1 +#define NN_PROTO_PUBSUB 2 +#define NN_PROTO_REQREP 3 +#define NN_PROTO_PIPELINE 5 +#define NN_PROTO_SURVEY 6 +#define NN_PROTO_BUS 7 + +#define NN_PAIR (NN_PROTO_PAIR * 16 + 0) +#define NN_PAIR_v0 (NN_PROTO_PAIR * 16 + 0) +#define NN_PAIR_V1 (NN_PROTO_PAIR * 16 + 1) +#define NN_PUB (NN_PROTO_PUBSUB * 16 + 0) +#define NN_SUB (NN_PROTO_PUBSUB * 16 + 1) +#define NN_REQ (NN_PROTO_REQREP * 16 + 0) +#define NN_REP (NN_PROTO_REQREP * 16 + 1) +#define NN_PUSH (NN_PROTO_PIPELINE * 16 + 0) +#define NN_PULL (NN_PROTO_PIPELINE * 16 + 1) +#define NN_SURVEYOR (NN_PROTO_SURVEY * 16 + 2) +#define NN_RESPONDENT (NN_PROTO_SURVEY * 16 + 3) +#define NN_BUS (NN_PROTO_BUS * 16 + 0) + +#define NN_SOCKADDR_MAX 128 +#define NN_SOL_SOCKET 0 + +// Flag for send/recv (nonblocking) +#define NN_DONTWAIT 1 + +// CMSG data type +#define PROTO_SP 1 +#define SP_HDR 1 + +// Errnos. Legacy nanomsg uses posix errnos where possible. +// If a define is not set, use add NN_ERRBASE. nng does not +// return all of these values, so there may be some loss of +// of information for edge cases, but we don't expect that to be +// a problem really. +#define NN_ERRBASE (0x10000000) +#ifndef ENOTSUP +#define ENOTSUP (NN_ERRBASE+1) +#endif +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT (NN_ERRBASE+2) +#endif +#ifndef ENOBUFS +#define ENOBUFS (NN_ERRBASE+3) +#endif +#ifndef ENETDOWN +#define ENETDOWN (NN_ERRBASE+4) +#endif +#ifndef EADDRINUSE +#define EADDRINUSE (NN_ERRBASE+5) +#endif +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL (NN_ERRBASE+6) +#endif +#ifndef ENOTSOCK +#define ENOTSOCK (NN_ERRBASE+7) +#endif +#ifndef EAGAIN +#define EAGAIN (NN_ERRBASE+8) +#endif +#ifndef EBADF +#define EBADF (NN_ERRBASE+9) +#endif +#ifndef EINVAL +#define EINVAL (NN_ERRBASE+10) +#endif +#ifndef EMFILE +#define EMFILE (NN_ERRBASE+11) +#endif +#ifndef EFAULT +#define EFAULT (NN_ERRBASE+12) +#endif +#ifndef EACCES +#define EACCES (NN_ERRBASE+13) +#endif +#ifndef ENETRESET +#define ENETRESET (NN_ERRBASE+14) +#endif +#ifndef ENETUNREACH +#define ENETUNREACH (NN_ERRBASE+15) +#endif +#ifndef EHOSTUNREACH +#define EHOSTUNREACH (NN_ERRBASE+16) +#endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT (NN_ERRBASE+17) +#endif +#ifndef EINPROGRESS +#define EINPROGRESS (NN_ERRBASE+18) +#endif +#ifndef EPROTO +#define EPROTO (NN_ERRBASE+19) +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED (NN_ERRBASE+20) +#endif +#ifndef ENOTCONN +#define ENOTCONN (NN_ERRBASE+21) +#endif +#ifndef EMSGSIZE +#define EMSGSIZE (NN_ERRBASE+22) +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT (NN_ERRBASE+23) +#endif +#ifndef ECONNABORTED +#define ECONNABORTED (NN_ERRBASE+24) +#endif +#ifndef ECONNRESET +#define ECONNRESET (NN_ERRBASE+25) +#endif +#ifndef ENOPROTOOPT +#define ENOPROTOOPT (NN_ERRBASE+26) +#endif +#ifndef EISCONN +#define EISCONN (NN_ERRBASE+27) +#endif +#ifndef ESOCKNOSUPPORT +#define ESOCKNOSPPORT (NN_ERRBASE+28) +#endif +#ifndef ETERM +#define ETERM (NN_ERRBASE+29) +#endif +#ifndef EFSM +#define EFSM (NN_ERRBASE+30) +#endif +#ifndef ENOENT +#define ENOENT (NN_ERRBASE+31) +#endif +#ifndef EIO +#define EIO (NN_ERRBASE+32) +#endif + +// Socket options +#define NN_LINGER 1 +#define NN_SNDBUF 2 +#define NN_RCVBUF 3 +#define NN_SNDTIMEO 4 +#define NN_RCVTIMEO 5 +#define NN_RECONNECT_IVL 6 +#define NN_RECONNECT_IVL_MAX 7 +#define NN_SNDPRIO 8 +#define NN_RCVPRIO 9 +#define NN_SNDFD 10 +#define NN_RCVFD 11 +#define NN_DOMAIN 12 +#define NN_PROTOCOL 13 +#define NN_IPV4ONLY 14 +#define NN_SOCKET_NAME 15 +#define NN_RCVMAXSIZE 16 +#define NN_MAXTTL 17 + +// Protocol-specific options. To simplify thins we encode the protocol +// level in the option. +#define NN_SUB_SUBSCRIBE (NN_SUB * 16 + 1) +#define NN_SUB_UNSUBSCRIBE (NN_SUB * 16 + 2) +#define NN_REQ_RESEND_IVL (NN_REQ * 16 + 1) +#define NN_SURVEYOR_DEADLINE (NN_SURVEYOR * 16 + 1) + +// Level options for tranports +#define NN_INPROC (-1) +#define NN_IPC (-2) +#define NN_IPC_SEC_ATTR 1 +#define NN_IPC_OUTBUFSZ 2 +#define NN_IPC_INBUFSZ 3 +#define NN_TCP (-3) +#define NN_TCP_NODELAY 1 +#define NN_WS (-4) +#define NN_WS_MSG_TYPE 1 +#define NN_WS_MSG_TYPE_TEXT 1 +#define NN_WS_MSG_TYPE_BINARY 2 + +// from this point on formatting is fine +// clang-format on + +// Poll stuff +#define NN_POLLIN 1 +#define NN_POLLOUT 2 +struct nn_pollfd { + int fd; + uint16_t events; + uint16_t revents; +}; + +// Magical size for allocation +#define NN_MSG ((size_t) -1) + +struct nn_iovec { + void * iov_base; + size_t iov_len; +}; + +struct nn_msghdr { + struct nn_iovec *msg_iov; + int msg_iovlen; + void * msg_control; + size_t msg_controllen; +}; + +struct nn_cmsghdr { + size_t cmsg_len; + int cmsg_level; + int cmsg_type; +}; + +#define NN_CMSG_ALIGN(len) \ + (((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1)) + +// Unlike old nanomsg, we explicitly only support the SP header as attached +// cmsg data. It turns out that old nanomsg didn't really store anything +// useful otherwise anyway. (One specific exception was that it stored the +// message type of text or binary for the websocket transport. We don't think +// anyone used that in practice though.) +#define NN_CMSG_FIRSTHDR(mh) nn_cmsg_next((struct nn_msghdr *) (mh), NULL) +#define NN_CMSG_NXTHDR(mh, ch) \ + nn_cmsg_next((struct nn_msghdr *) (mh), (struct nn_cmsghdr *) ch) +#define NN_CMSG_DATA(ch) ((unsigned char *) (((struct nn_cmsghdr *) (ch)) + 1)) +#define NN_CMSG_SPACE(len) \ + (NN_CMSG_ALIGN(len) + NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr))) +#define NN_CMSG_LEN(len) (NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr)) + (len)) + +NN_DECL struct nn_cmsghdr *nn_cmsg_next( + struct nn_msghdr *, struct nn_cmsghdr *); +NN_DECL int nn_socket(int, int); +NN_DECL int nn_setsockopt(int, int, int, const void *, size_t); +NN_DECL int nn_getsockopt(int, int, int, void *, size_t *); +NN_DECL int nn_bind(int, const char *); +NN_DECL int nn_connect(int, const char *); +NN_DECL int nn_shutdown(int, int); +NN_DECL int nn_send(int, const void *, size_t, int); +NN_DECL int nn_recv(int, void *, size_t, int); +NN_DECL int nn_sendmsg(int, const struct nn_msghdr *, int); +NN_DECL int nn_recvmsg(int, struct nn_msghdr *, int); +NN_DECL int nn_close(int); +NN_DECL int nn_poll(struct nn_pollfd *, int, int); +NN_DECL int nn_device(int, int); +NN_DECL uint64_t nn_get_statistic(int, int); +NN_DECL void * nn_allocmsg(size_t, int); +NN_DECL void * nn_reallocmsg(void *, size_t); +NN_DECL int nn_freemsg(void *); +NN_DECL int nn_errno(void); +NN_DECL const char *nn_strerror(int); +NN_DECL void nn_term(void); + +#ifdef __cplusplus +} +#endif + +#endif // NNG_COMPAT_H diff --git a/src/nng_compat.c b/src/nng_compat.c deleted file mode 100644 index 35bacb6f..00000000 --- a/src/nng_compat.c +++ /dev/null @@ -1,728 +0,0 @@ -// -// Copyright 2017 Garrett D'Amore -// Copyright 2017 Capitar IT Group BV -// -// 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. -// - -#include "nng_compat.h" -#include "nng.h" -#include "protocol/bus0/bus.h" -#include "protocol/pair0/pair.h" -#include "protocol/pipeline0/pull.h" -#include "protocol/pipeline0/push.h" -#include "protocol/pubsub0/pub.h" -#include "protocol/pubsub0/sub.h" -#include "protocol/reqrep0/rep.h" -#include "protocol/reqrep0/req.h" -#include "protocol/survey0/respond.h" -#include "protocol/survey0/survey.h" - -#include -#include - -// This file supplies the legacy compatibility API. Applications should -// avoid using these if at all possible, and instead use the new style APIs. - -static const struct { - int nerr; - int perr; -} nn_errnos[] = { - // clang-format off - { NNG_EINTR, EINTR }, - { NNG_ENOMEM, ENOMEM }, - { NNG_EINVAL, EINVAL }, - { NNG_EBUSY, EBUSY }, - { NNG_ETIMEDOUT, ETIMEDOUT }, - { NNG_ECONNREFUSED, ECONNREFUSED }, - { NNG_ECLOSED, EBADF }, - { NNG_EAGAIN, EAGAIN }, - { NNG_ENOTSUP, ENOTSUP }, - { NNG_EADDRINUSE, EADDRINUSE }, - { NNG_ESTATE, EFSM }, - { NNG_ENOENT, ENOENT }, - { NNG_EPROTO, EPROTO }, - { NNG_EUNREACHABLE, EHOSTUNREACH }, - { NNG_EADDRINVAL, EADDRNOTAVAIL }, - { NNG_EPERM, EACCES }, - { NNG_EMSGSIZE, EMSGSIZE }, - { NNG_ECONNABORTED, ECONNABORTED }, - { NNG_ECONNRESET, ECONNRESET }, - { NNG_ECANCELED, EBADF }, - { 0, 0 }, - // clang-format on -}; - -const char * -nn_strerror(int err) -{ - int i; - static char msgbuf[32]; - - for (i = 0; nn_errnos[i].perr != 0; i++) { - if (nn_errnos[i].perr == err) { - return (nng_strerror(nn_errnos[i].nerr)); - } - } - if (err == EIO) { - return ("Unknown I/O error"); - } - - // Arguably we could use strerror() here, but we should only - // be getting errnos we understand at this point. - (void) snprintf(msgbuf, sizeof(msgbuf), "Unknown error %d", err); - return (msgbuf); -} - -static void -nn_seterror(int err) -{ - int i; - - for (i = 0; nn_errnos[i].nerr != 0; i++) { - if (nn_errnos[i].nerr == err) { - errno = nn_errnos[i].perr; - return; - } - } - // No idea... - errno = EIO; -} - -int -nn_errno(void) -{ - return (errno); -} - -static const struct { - uint16_t p_id; - int (*p_open)(nng_socket *); -} nn_protocols[] = { -// clang-format off -#ifdef NNG_HAVE_BUS0 - { NN_BUS, nng_bus0_open }, -#endif -#ifdef NNG_HAVE_PAIR0 - { NN_PAIR, nng_pair0_open }, -#endif -#ifdef NNG_HAVE_PUSH0 - { NN_PUSH, nng_push0_open }, -#endif -#ifdef NNG_HAVE_PULL0 - { NN_PULL, nng_pull0_open }, -#endif -#ifdef NNG_HAVE_PUB0 - { NN_PUB, nng_pub0_open }, -#endif -#ifdef NNG_HAVE_SUB0 - { NN_SUB, nng_sub0_open }, -#endif -#ifdef NNG_HAVE_REQ0 - { NN_REQ, nng_req0_open }, -#endif -#ifdef NNG_HAVE_REP0 - { NN_REP, nng_rep0_open }, -#endif -#ifdef NNG_HAVE_SURVEYOR0 - { NN_SURVEYOR, nng_surveyor0_open }, -#endif -#ifdef NNG_HAVE_RESPONDENT0 - { NN_RESPONDENT, nng_respondent0_open }, -#endif - { 0, NULL }, - // clang-format on -}; - -int -nn_socket(int domain, int protocol) -{ - nng_socket sock; - int rv; - int i; - - if ((domain != AF_SP) && (domain != AF_SP_RAW)) { - errno = EAFNOSUPPORT; - return (-1); - } - - for (i = 0; nn_protocols[i].p_id != 0; i++) { - if (nn_protocols[i].p_id == protocol) { - break; - } - } - if (nn_protocols[i].p_open == NULL) { - errno = ENOTSUP; - return (-1); - } - - if ((rv = nn_protocols[i].p_open(&sock)) != 0) { - nn_seterror(rv); - return (-1); - } - if (domain == AF_SP_RAW) { - if ((rv = nng_setopt_int(sock, NNG_OPT_RAW, 1)) != 0) { - nn_seterror(rv); - nng_close(sock); - return (-1); - } - } - return ((int) sock); -} - -int -nn_close(int s) -{ - int rv; - - if ((rv = nng_close((nng_socket) s)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -int -nn_bind(int s, const char *addr) -{ - int rv; - nng_listener l; - - if ((rv = nng_listen((nng_socket) s, addr, &l, 0)) != 0) { - nn_seterror(rv); - return (-1); - } - return ((int) l); -} - -int -nn_connect(int s, const char *addr) -{ - int rv; - nng_dialer d; - - if ((rv = nng_dial((nng_socket) s, addr, &d, NNG_FLAG_NONBLOCK)) != - 0) { - nn_seterror(rv); - return (-1); - } - return ((int) d); -} - -int -nn_shutdown(int s, int ep) -{ - int rv; - (void) s; // Unused - - // Socket is wired into the endpoint... so passing a bad endpoint - // ID can result in affecting the wrong socket. But this requires - // a buggy application, and because we don't recycle endpoints - // until wrap, its unlikely to actually come up in practice. - // Note that listeners and dialers share the same namespace - // in the core, so we can close either one this way. - - if (((rv = nng_dialer_close((nng_dialer) ep)) != 0) && - ((rv = nng_listener_close((nng_listener) ep)) != 0)) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -void * -nn_allocmsg(size_t size, int type) -{ - nng_msg *msg; - int rv; - - // Validate type and non-zero size. This also checks for overflow. - if ((type != 0) || (size < 1) || ((size + sizeof(msg) < size))) { - nn_seterror(NNG_EINVAL); - return (NULL); - } - - // So our "messages" from nn are really going to be nng messages - // but to make this work, we use a bit of headroom in the message - // to stash the message header. - if ((rv = nng_msg_alloc(&msg, size + (sizeof(msg)))) != 0) { - nn_seterror(rv); - return (NULL); - } - - // This counts on message bodies being aligned sensibly. - *(nng_msg **) (nng_msg_body(msg)) = msg; - - // We are counting on the implementation of nn_msg_trim to not - // reallocate the message but just to leave the prefix inplace. - (void) nng_msg_trim(msg, sizeof(msg)); - - return (nng_msg_body(msg)); -} - -int -nn_freemsg(void *ptr) -{ - nng_msg *msg; - - msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); - nng_msg_free(msg); - return (0); -} - -void * -nn_reallocmsg(void *ptr, size_t len) -{ - nng_msg *msg; - int rv; - - if ((len + sizeof(msg)) < len) { - // overflowed! - nn_seterror(NNG_EINVAL); - return (NULL); - } - - // This counts on message bodies being aligned sensibly. - msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); - - // We need to realloc the requested len, plus size for our header. - if ((rv = nng_msg_realloc(msg, len + sizeof(msg))) != 0) { - // We don't free the old message. Code is free to cope - // as it sees fit. - nn_seterror(rv); - return (NULL); - } - // Stash the msg header pointer - *(nng_msg **) (nng_msg_body(msg)) = msg; - nng_msg_trim(msg, sizeof(msg)); - return (nng_msg_body(msg)); -} - -static int -nn_flags(int flags) -{ - switch (flags) { - case 0: - return (0); - - case NN_DONTWAIT: - return (NNG_FLAG_NONBLOCK); - - default: - nn_seterror(NNG_EINVAL); - return (-1); - } -} - -int -nn_send(int s, const void *buf, size_t len, int flags) -{ - struct nn_iovec iov; - struct nn_msghdr hdr; - - iov.iov_base = (void *) buf; - iov.iov_len = len; - - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - hdr.msg_control = NULL; - hdr.msg_controllen = 0; - - return (nn_sendmsg(s, &hdr, flags)); -} - -int -nn_recv(int s, void *buf, size_t len, int flags) -{ - struct nn_iovec iov; - struct nn_msghdr hdr; - - iov.iov_base = buf; - iov.iov_len = len; - - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - hdr.msg_control = NULL; - hdr.msg_controllen = 0; - - return (nn_recvmsg(s, &hdr, flags)); -} - -int -nn_recvmsg(int s, struct nn_msghdr *mh, int flags) -{ - int rv; - nng_msg *msg; - size_t len; - int keep = 0; - - if ((flags = nn_flags(flags)) == -1) { - return (-1); - } - if (mh == NULL) { - nn_seterror(NNG_EINVAL); - return (-1); - } - if (mh->msg_iovlen < 0) { - nn_seterror(NNG_EMSGSIZE); - return (-1); - } - - if ((rv = nng_recvmsg((nng_socket) s, &msg, flags)) != 0) { - nn_seterror(rv); - return (-1); - } - if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { - // Receiver wants to have a dynamically allocated message. - // There can only be one of these. - if ((rv = nng_msg_insert(msg, &msg, sizeof(msg))) != 0) { - nng_msg_free(msg); - nn_seterror(rv); - return (-1); - } - nng_msg_trim(msg, sizeof(msg)); - *(void **) (mh->msg_iov[0].iov_base) = nng_msg_body(msg); - len = nng_msg_len(msg); - keep = 1; // Do not discard message! - } else { - // copyout to multiple iovecs. - char * ptr = nng_msg_body(msg); - int i; - size_t n; - len = nng_msg_len(msg); - - for (i = 0; i < mh->msg_iovlen; i++) { - if ((n = mh->msg_iov[i].iov_len) == NN_MSG) { - // This is forbidden! - nn_seterror(NNG_EINVAL); - nng_msg_free(msg); - return (-1); - } - if (n > len) { - n = len; - } - memcpy(mh->msg_iov[i].iov_base, ptr, n); - len -= n; - ptr += n; - } - - // If we copied everything, len will be zero, otherwise, - // it represents the amount of data that we were unable to - // copyout. The caller is responsible for noticing this, - // as there is no API to pass this information out. - len = nng_msg_len(msg); - } - - // If the caller has requested control information (header details), - // we grab it. - if (mh->msg_control != NULL) { - char * cdata; - size_t clen; - size_t tlen; - size_t spsz; - struct nn_cmsghdr *hdr; - unsigned char * ptr; - - spsz = nng_msg_header_len(msg); - clen = NN_CMSG_SPACE(sizeof(spsz) + spsz); - - if ((tlen = mh->msg_controllen) == NN_MSG) { - // Ideally we'd use the same msg, but we would need - // to set up reference counts on the message, so - // instead we just make a new message. - nng_msg *nmsg; - - rv = nng_msg_alloc(&nmsg, clen + sizeof(nmsg)); - if (rv != 0) { - nng_msg_free(msg); - nn_seterror(rv); - return (-1); - } - memcpy(nng_msg_body(nmsg), &nmsg, sizeof(nmsg)); - nng_msg_trim(nmsg, sizeof(nmsg)); - cdata = nng_msg_body(nmsg); - *(void **) mh->msg_control = cdata; - tlen = clen; - } else { - cdata = mh->msg_control; - memset(cdata, 0, - tlen > sizeof(*hdr) ? sizeof(*hdr) : tlen); - } - - if (clen <= tlen) { - ptr = NN_CMSG_DATA(cdata); - hdr = (void *) cdata; - hdr->cmsg_len = clen; - hdr->cmsg_level = PROTO_SP; - hdr->cmsg_type = SP_HDR; - - memcpy(ptr, &spsz, sizeof(spsz)); - ptr += sizeof(spsz); - memcpy(ptr, nng_msg_header(msg), spsz); - } - } - - if (!keep) { - nng_msg_free(msg); - } - return ((int) len); -} - -int -nn_sendmsg(int s, const struct nn_msghdr *mh, int flags) -{ - nng_msg *msg = NULL; - nng_msg *cmsg = NULL; - char * cdata; - int keep = 0; - size_t sz; - int rv; - - if ((flags = nn_flags(flags)) == -1) { - return (-1); - } - - if (mh == NULL) { - nn_seterror(NNG_EINVAL); - return (-1); - } - - if (mh->msg_iovlen < 0) { - nn_seterror(NNG_EMSGSIZE); - return (-1); - } - - if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { - char *bufp = *(char **) (mh->msg_iov[0].iov_base); - - msg = *(nng_msg **) (bufp - sizeof(msg)); - keep = 1; // keep the message on error - } else { - char *ptr; - int i; - - sz = 0; - // Get the total message size. - for (i = 0; i < mh->msg_iovlen; i++) { - sz += mh->msg_iov[i].iov_len; - } - if ((rv = nng_msg_alloc(&msg, sz)) != 0) { - nn_seterror(rv); - return (-1); - } - // Now copy it out. - ptr = nng_msg_body(msg); - for (i = 0; i < mh->msg_iovlen; i++) { - memcpy(ptr, mh->msg_iov[i].iov_base, - mh->msg_iov[i].iov_len); - ptr += mh->msg_iov[i].iov_len; - } - } - - // Now suck up the control data... - // This POSIX-inspired API is one of the most painful for - // usability we've ever seen. - cmsg = NULL; - if ((cdata = mh->msg_control) != NULL) { - size_t clen; - size_t offs; - size_t spsz; - struct nn_cmsghdr *chdr; - unsigned char * data; - - if ((clen = mh->msg_controllen) == NN_MSG) { - // Underlying data is a message. This is awkward, - // because we have to copy the data, but we should - // only free this message on success. So we save the - // message now. - cdata = *(void **) cdata; - cmsg = *(nng_msg **) (cdata - sizeof(cmsg)); - clen = nng_msg_len(cmsg); - } else { - clen = mh->msg_controllen; - } - - offs = 0; - while ((offs + sizeof(NN_CMSG_LEN(0))) < clen) { - chdr = (void *) (cdata + offs); - if ((chdr->cmsg_level != PROTO_SP) || - (chdr->cmsg_type != SP_HDR)) { - offs += chdr->cmsg_len; - } - - // SP header in theory. Starts with size, then - // any backtrace details. - if (chdr->cmsg_len < sizeof(size_t)) { - offs += chdr->cmsg_len; - continue; - } - data = NN_CMSG_DATA(chdr); - memcpy(&spsz, data, sizeof(spsz)); - if ((spsz + sizeof(spsz)) > chdr->cmsg_len) { - // Truncated header? Ignore it. - offs += chdr->cmsg_len; - continue; - } - data += sizeof(spsz); - rv = nng_msg_header_append(msg, data, spsz); - if (rv != 0) { - if (!keep) { - nng_msg_free(msg); - } - nn_seterror(rv); - return (-1); - } - - break; - } - } - - sz = nng_msg_len(msg); - if ((rv = nng_sendmsg((nng_socket) s, msg, flags)) != 0) { - if (!keep) { - nng_msg_free(msg); - } - nn_seterror(rv); - return (-1); - } - - if (cmsg != NULL) { - // We sent successfully, so free up the control message. - nng_msg_free(cmsg); - } - return ((int) sz); -} - -// options which we convert -- most of the array is initialized at run time. -static const struct { - int nnlevel; - int nnopt; - const char *opt; -} options[] = { - { NN_SOL_SOCKET, NN_LINGER, NNG_OPT_LINGER }, // review - { NN_SOL_SOCKET, NN_SNDBUF, NNG_OPT_SENDBUF }, - { NN_SOL_SOCKET, NN_RCVBUF, NNG_OPT_RECVBUF }, - { NN_SOL_SOCKET, NN_RECONNECT_IVL, NNG_OPT_RECONNMINT }, - { NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, NNG_OPT_RECONNMAXT }, - { NN_SOL_SOCKET, NN_SNDFD, NNG_OPT_SENDFD }, - { NN_SOL_SOCKET, NN_RCVFD, NNG_OPT_RECVFD }, - { NN_SOL_SOCKET, NN_RCVMAXSIZE, NNG_OPT_RECVMAXSZ }, - { NN_SOL_SOCKET, NN_MAXTTL, NNG_OPT_MAXTTL }, - { NN_SOL_SOCKET, NN_RCVTIMEO, NNG_OPT_RECVTIMEO }, - { NN_SOL_SOCKET, NN_SNDTIMEO, NNG_OPT_SENDTIMEO }, - { NN_SOL_SOCKET, NN_DOMAIN, NNG_OPT_DOMAIN }, - { NN_SOL_SOCKET, NN_SOCKET_NAME, NNG_OPT_SOCKNAME }, - { NN_REQ, NN_REQ_RESEND_IVL, NNG_OPT_REQ_RESENDTIME }, - { NN_SUB, NN_SUB_SUBSCRIBE, NNG_OPT_SUB_SUBSCRIBE }, - { NN_SUB, NN_SUB_UNSUBSCRIBE, NNG_OPT_SUB_UNSUBSCRIBE }, - { NN_SURVEYOR, NN_SURVEYOR_DEADLINE, NNG_OPT_SURVEYOR_SURVEYTIME }, - // XXX: IPV4ONLY, SNDPRIO, RCVPRIO -}; - -int -nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) -{ - const char *name = NULL; - int rv; - - for (unsigned i = 0; i < sizeof(options) / sizeof(options[0]); i++) { - if ((options[i].nnlevel == nnlevel) && - (options[i].nnopt == nnopt)) { - name = options[i].opt; - break; - } - } - - if (name == NULL) { - errno = ENOPROTOOPT; - return (-1); - } - - if ((rv = nng_getopt((nng_socket) s, name, valp, szp)) != 0) { - nn_seterror(rv); - return (-1); - } - - return (0); -} - -int -nn_setsockopt(int s, int nnlevel, int nnopt, const void *valp, size_t sz) -{ - const char *name = NULL; - int rv; - - for (unsigned i = 0; i < sizeof(options) / sizeof(options[0]); i++) { - if ((options[i].nnlevel == nnlevel) && - (options[i].nnopt == nnopt)) { - name = options[i].opt; - break; - } - } - if (name == NULL) { - return (ENOPROTOOPT); - } - - if ((rv = nng_setopt((nng_socket) s, name, valp, sz)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -struct nn_cmsghdr * -nn_cmsg_next(struct nn_msghdr *mh, struct nn_cmsghdr *first) -{ - size_t clen; - char * data; - - // We only support SP headers, so there can be at most one header. - if (first != NULL) { - return (NULL); - } - if ((clen = mh->msg_controllen) == NN_MSG) { - nng_msg *msg; - data = *((void **) (mh->msg_control)); - msg = *(nng_msg **) (data - sizeof(msg)); - clen = nng_msg_len(msg); - } else { - data = mh->msg_control; - } - - if (first == NULL) { - first = (void *) data; - } else { - first = first + first->cmsg_len; - } - - if (((char *) first + sizeof(*first)) > (data + clen)) { - return (NULL); - } - return (first); -} - -int -nn_device(int s1, int s2) -{ - int rv; - - rv = nng_device((nng_socket) s1, (nng_socket) s2); - // rv must always be nonzero - nn_seterror(rv); - return (-1); -} - -// nn_term is suitable only for shutting down the entire library, -// and is not thread-safe with other functions. -void -nn_term(void) -{ - // This function is relatively toxic, since it can affect - // all sockets in the process, including those - // in use by libraries, etc. Accordingly, do not use this - // in a library -- only e.g. atexit() and similar. - nng_closeall(); -} diff --git a/src/nng_compat.h b/src/nng_compat.h deleted file mode 100644 index 8c5cee6f..00000000 --- a/src/nng_compat.h +++ /dev/null @@ -1,315 +0,0 @@ -// -// Copyright 2017 Garrett D'Amore -// Copyright 2017 Capitar IT Group BV -// -// 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_COMPAT_H -#define NNG_COMPAT_H - -// This header contains interfaces that are intended to offer compatibility -// with nanomsg v1.0. These are not the "preferred" interfaces for nng, -// and consumers should only use thse if they are porting software that -// previously used nanomsg. New programs should use the nng native APIs. - -// Note that compatibility promises are limited to public portions of the -// nanomsg API, and specifically do NOT extend to the ABI. Furthermore, -// there may be other limitations around less commonly used portions of the -// API; for example only SP headers may be transported in control data for -// messages, there is almost no compatibility offered for statistics. -// Error values may differ from those returned by nanomsg as well; the nng -// error reporting facility expresses only a subset of the possibilities of -// nanomsg. - -// Note that unlinke nanomsg, nng does not aggressively recycle socket or -// endpoint IDs, which means applications which made assumptions that these -// would be relatively small integers (e.g. to use them as array indices) -// may break. (No promise about values was ever made.) - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -// clang-format gets in the way of most of this file. -// We turn it off, at least until it gets smarter about aligning -// macro definitions or we adopt enums or somesuch. -// clang-format off - -// NNG_DECL is used on declarations to deal with scope. -// For building Windows DLLs, it should be the appropriate -// __declspec(). (We recommend *not* building this library -// as a DLL, but instead linking it statically for your projects -// to minimize questions about link dependencies later.) -#ifndef NN_DECL -#if defined(_WIN32) && !defined(NNG_STATIC_LIB) -#if defined(NNG_SHARED_LIB) -#define NN_DECL __declspec(dllexport) -#else -#define NN_DECL __declspec(dllimport) -#endif // NNG_SHARED_LIB -#else -#define NN_DECL extern -#endif // _WIN32 && !NNG_STATIC_LIB -#endif // NN_DECL - -#define AF_SP 1 -#define AF_SP_RAW 2 - -// Protocol stuff -#define NN_PROTO_PAIR 1 -#define NN_PROTO_PUBSUB 2 -#define NN_PROTO_REQREP 3 -#define NN_PROTO_PIPELINE 5 -#define NN_PROTO_SURVEY 6 -#define NN_PROTO_BUS 7 - -#define NN_PAIR (NN_PROTO_PAIR * 16 + 0) -#define NN_PAIR_v0 (NN_PROTO_PAIR * 16 + 0) -#define NN_PAIR_V1 (NN_PROTO_PAIR * 16 + 1) -#define NN_PUB (NN_PROTO_PUBSUB * 16 + 0) -#define NN_SUB (NN_PROTO_PUBSUB * 16 + 1) -#define NN_REQ (NN_PROTO_REQREP * 16 + 0) -#define NN_REP (NN_PROTO_REQREP * 16 + 1) -#define NN_PUSH (NN_PROTO_PIPELINE * 16 + 0) -#define NN_PULL (NN_PROTO_PIPELINE * 16 + 1) -#define NN_SURVEYOR (NN_PROTO_SURVEY * 16 + 2) -#define NN_RESPONDENT (NN_PROTO_SURVEY * 16 + 3) -#define NN_BUS (NN_PROTO_BUS * 16 + 0) - -#define NN_SOCKADDR_MAX 128 -#define NN_SOL_SOCKET 0 - -// Flag for send/recv (nonblocking) -#define NN_DONTWAIT 1 - -// CMSG data type -#define PROTO_SP 1 -#define SP_HDR 1 - -// Errnos. Legacy nanomsg uses posix errnos where possible. -// If a define is not set, use add NN_ERRBASE. nng does not -// return all of these values, so there may be some loss of -// of information for edge cases, but we don't expect that to be -// a problem really. -#define NN_ERRBASE (0x10000000) -#ifndef ENOTSUP -#define ENOTSUP (NN_ERRBASE+1) -#endif -#ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT (NN_ERRBASE+2) -#endif -#ifndef ENOBUFS -#define ENOBUFS (NN_ERRBASE+3) -#endif -#ifndef ENETDOWN -#define ENETDOWN (NN_ERRBASE+4) -#endif -#ifndef EADDRINUSE -#define EADDRINUSE (NN_ERRBASE+5) -#endif -#ifndef EADDRNOTAVAIL -#define EADDRNOTAVAIL (NN_ERRBASE+6) -#endif -#ifndef ENOTSOCK -#define ENOTSOCK (NN_ERRBASE+7) -#endif -#ifndef EAGAIN -#define EAGAIN (NN_ERRBASE+8) -#endif -#ifndef EBADF -#define EBADF (NN_ERRBASE+9) -#endif -#ifndef EINVAL -#define EINVAL (NN_ERRBASE+10) -#endif -#ifndef EMFILE -#define EMFILE (NN_ERRBASE+11) -#endif -#ifndef EFAULT -#define EFAULT (NN_ERRBASE+12) -#endif -#ifndef EACCES -#define EACCES (NN_ERRBASE+13) -#endif -#ifndef ENETRESET -#define ENETRESET (NN_ERRBASE+14) -#endif -#ifndef ENETUNREACH -#define ENETUNREACH (NN_ERRBASE+15) -#endif -#ifndef EHOSTUNREACH -#define EHOSTUNREACH (NN_ERRBASE+16) -#endif -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT (NN_ERRBASE+17) -#endif -#ifndef EINPROGRESS -#define EINPROGRESS (NN_ERRBASE+18) -#endif -#ifndef EPROTO -#define EPROTO (NN_ERRBASE+19) -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED (NN_ERRBASE+20) -#endif -#ifndef ENOTCONN -#define ENOTCONN (NN_ERRBASE+21) -#endif -#ifndef EMSGSIZE -#define EMSGSIZE (NN_ERRBASE+22) -#endif -#ifndef ETIMEDOUT -#define ETIMEDOUT (NN_ERRBASE+23) -#endif -#ifndef ECONNABORTED -#define ECONNABORTED (NN_ERRBASE+24) -#endif -#ifndef ECONNRESET -#define ECONNRESET (NN_ERRBASE+25) -#endif -#ifndef ENOPROTOOPT -#define ENOPROTOOPT (NN_ERRBASE+26) -#endif -#ifndef EISCONN -#define EISCONN (NN_ERRBASE+27) -#endif -#ifndef ESOCKNOSUPPORT -#define ESOCKNOSPPORT (NN_ERRBASE+28) -#endif -#ifndef ETERM -#define ETERM (NN_ERRBASE+29) -#endif -#ifndef EFSM -#define EFSM (NN_ERRBASE+30) -#endif -#ifndef ENOENT -#define ENOENT (NN_ERRBASE+31) -#endif -#ifndef EIO -#define EIO (NN_ERRBASE+32) -#endif - -// Socket options -#define NN_LINGER 1 -#define NN_SNDBUF 2 -#define NN_RCVBUF 3 -#define NN_SNDTIMEO 4 -#define NN_RCVTIMEO 5 -#define NN_RECONNECT_IVL 6 -#define NN_RECONNECT_IVL_MAX 7 -#define NN_SNDPRIO 8 -#define NN_RCVPRIO 9 -#define NN_SNDFD 10 -#define NN_RCVFD 11 -#define NN_DOMAIN 12 -#define NN_PROTOCOL 13 -#define NN_IPV4ONLY 14 -#define NN_SOCKET_NAME 15 -#define NN_RCVMAXSIZE 16 -#define NN_MAXTTL 17 - -// Protocol-specific options. To simplify thins we encode the protocol -// level in the option. -#define NN_SUB_SUBSCRIBE (NN_SUB * 16 + 1) -#define NN_SUB_UNSUBSCRIBE (NN_SUB * 16 + 2) -#define NN_REQ_RESEND_IVL (NN_REQ * 16 + 1) -#define NN_SURVEYOR_DEADLINE (NN_SURVEYOR * 16 + 1) - -// Level options for tranports -#define NN_INPROC (-1) -#define NN_IPC (-2) -#define NN_IPC_SEC_ATTR 1 -#define NN_IPC_OUTBUFSZ 2 -#define NN_IPC_INBUFSZ 3 -#define NN_TCP (-3) -#define NN_TCP_NODELAY 1 -#define NN_WS (-4) -#define NN_WS_MSG_TYPE 1 -#define NN_WS_MSG_TYPE_TEXT 1 -#define NN_WS_MSG_TYPE_BINARY 2 - -// from this point on formatting is fine -// clang-format on - -// Poll stuff -#define NN_POLLIN 1 -#define NN_POLLOUT 2 -struct nn_pollfd { - int fd; - uint16_t events; - uint16_t revents; -}; - -// Magical size for allocation -#define NN_MSG ((size_t) -1) - -struct nn_iovec { - void * iov_base; - size_t iov_len; -}; - -struct nn_msghdr { - struct nn_iovec *msg_iov; - int msg_iovlen; - void * msg_control; - size_t msg_controllen; -}; - -struct nn_cmsghdr { - size_t cmsg_len; - int cmsg_level; - int cmsg_type; -}; - -#define NN_CMSG_ALIGN(len) \ - (((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1)) - -// Unlike old nanomsg, we explicitly only support the SP header as attached -// cmsg data. It turns out that old nanomsg didn't really store anything -// useful otherwise anyway. (One specific exception was that it stored the -// message type of text or binary for the websocket transport. We don't think -// anyone used that in practice though.) -#define NN_CMSG_FIRSTHDR(mh) nn_cmsg_next((struct nn_msghdr *) (mh), NULL) -#define NN_CMSG_NXTHDR(mh, ch) \ - nn_cmsg_next((struct nn_msghdr *) (mh), (struct nn_cmsghdr *) ch) -#define NN_CMSG_DATA(ch) ((unsigned char *) (((struct nn_cmsghdr *) (ch)) + 1)) -#define NN_CMSG_SPACE(len) \ - (NN_CMSG_ALIGN(len) + NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr))) -#define NN_CMSG_LEN(len) (NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr)) + (len)) - -NN_DECL struct nn_cmsghdr *nn_cmsg_next( - struct nn_msghdr *, struct nn_cmsghdr *); -NN_DECL int nn_socket(int, int); -NN_DECL int nn_setsockopt(int, int, int, const void *, size_t); -NN_DECL int nn_getsockopt(int, int, int, void *, size_t *); -NN_DECL int nn_bind(int, const char *); -NN_DECL int nn_connect(int, const char *); -NN_DECL int nn_shutdown(int, int); -NN_DECL int nn_send(int, const void *, size_t, int); -NN_DECL int nn_recv(int, void *, size_t, int); -NN_DECL int nn_sendmsg(int, const struct nn_msghdr *, int); -NN_DECL int nn_recvmsg(int, struct nn_msghdr *, int); -NN_DECL int nn_close(int); -NN_DECL int nn_poll(struct nn_pollfd *, int, int); -NN_DECL int nn_device(int, int); -NN_DECL uint64_t nn_get_statistic(int, int); -NN_DECL void * nn_allocmsg(size_t, int); -NN_DECL void * nn_reallocmsg(void *, size_t); -NN_DECL int nn_freemsg(void *); -NN_DECL int nn_errno(void); -NN_DECL const char *nn_strerror(int); -NN_DECL void nn_term(void); - -#ifdef __cplusplus -} -#endif - -#endif // NNG_COMPAT_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 51903572..df7e5701 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,7 +3,7 @@ # Copyright (c) 2013 GoPivotal, Inc. All rights reserved. # Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved. # Copyright 2016 Franklin "Snaipe" Mathieu -# Copyright 2018 Garrett D'Amore +# Copyright 2018 Staysail Systems, Inc. # Copyright 2018 Capitar IT Group BV # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -53,9 +53,6 @@ if (NNG_TESTS) target_link_libraries (${NAME} ${PROJECT_NAME}_static) target_link_libraries (${NAME} ${NNG_REQUIRED_LIBRARIES}) target_compile_definitions(${NAME} PUBLIC -DNNG_STATIC_LIB) - if (CMAKE_THREAD_LIBS_INIT) - target_link_libraries (${NAME} "${CMAKE_THREAD_LIBS_INIT}") - endif() add_test (NAME ${NAME} COMMAND ${NAME} -v -p TEST_PORT=${TEST_PORT}) set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT}) @@ -81,9 +78,8 @@ if (NNG_TESTS) target_link_libraries (${NAME} ${PROJECT_NAME}_static) target_link_libraries (${NAME} ${NNG_REQUIRED_LIBRARIES}) target_compile_definitions(${NAME} PUBLIC -DNNG_STATIC_LIB) - if (CMAKE_THREAD_LIBS_INIT) - target_link_libraries (${NAME} "${CMAKE_THREAD_LIBS_INIT}") - endif() + target_include_directories(${NAME} PUBLIC + ${PROJECT_SOURCE_DIR}/src/compat) add_test (NAME ${NAME} COMMAND ${NAME} ${TEST_PORT}) set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT}) @@ -92,7 +88,7 @@ if (NNG_TESTS) else () macro (add_nng_compat_test NAME TIMEOUT) endmacro (add_nng_compat_test) - message (STATUS "Compatibility tests disabled (unconfigured legacy protocols)") + message (STATUS "Compatibility tests disabled (unconfigured protocols)") endif () macro (add_nng_cpp_test NAME TIMEOUT) @@ -103,9 +99,6 @@ if (NNG_TESTS) target_link_libraries (${NAME} ${PROJECT_NAME}_static) target_link_libraries (${NAME} ${NNG_REQUIRED_LIBRARIES}) target_compile_definitions(${NAME} PUBLIC -DNNG_STATIC_LIB) - if (CMAKE_THREAD_LIBS_INIT) - target_link_libraries (${NAME} "${CMAKE_THREAD_LIBS_INIT}") - endif() add_test (NAME ${NAME} COMMAND ${NAME} ${TEST_PORT}) set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT}) diff --git a/tests/compat_block.c b/tests/compat_block.c index e873cc86..65bd123c 100644 --- a/tests/compat_block.c +++ b/tests/compat_block.c @@ -20,7 +20,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" /* This test checks whether blocking on send/recv works as expected. */ diff --git a/tests/compat_bug777.c b/tests/compat_bug777.c index ba4a8b02..f5cfde6a 100644 --- a/tests/compat_bug777.c +++ b/tests/compat_bug777.c @@ -1,6 +1,6 @@ /* - Copyright 2017 Garrett D'Amore - Copyright 2017 Capitar IT Group BV + Copyright 2018 Staysail Systems, Inc. + Copyright 2018 Capitar IT Group BV Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -21,8 +21,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" -#include "nng.h" +#include #include "compat_testutil.h" int main (NN_UNUSED int argc, NN_UNUSED const char *argv[]) diff --git a/tests/compat_bus.c b/tests/compat_bus.c index ac4cc030..a8b380ab 100644 --- a/tests/compat_bus.c +++ b/tests/compat_bus.c @@ -20,7 +20,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" #define SOCKET_ADDRESS_A "inproc://a" diff --git a/tests/compat_cmsg.c b/tests/compat_cmsg.c index 4d70dabe..9484161b 100644 --- a/tests/compat_cmsg.c +++ b/tests/compat_cmsg.c @@ -1,6 +1,6 @@ /* Copyright (c) 2014 Martin Sustrik All rights reserved. - Copyright 2015 Garrett D'Amore + Copyright 2018 Garrett D'Amore Copyright 2016 Franklin "Snaipe" Mathieu Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,7 +22,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" int main (int argc, const char *argv[]) diff --git a/tests/compat_device.c b/tests/compat_device.c index e04839ef..21b9c16e 100644 --- a/tests/compat_device.c +++ b/tests/compat_device.c @@ -21,7 +21,7 @@ * IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" #define SOCKET_ADDRESS_A "inproc://a" diff --git a/tests/compat_iovec.c b/tests/compat_iovec.c index 44cb5deb..6a68e1ba 100644 --- a/tests/compat_iovec.c +++ b/tests/compat_iovec.c @@ -20,7 +20,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" diff --git a/tests/compat_msg.c b/tests/compat_msg.c index 683739d3..7618ea0a 100644 --- a/tests/compat_msg.c +++ b/tests/compat_msg.c @@ -23,7 +23,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" #include diff --git a/tests/compat_pair.c b/tests/compat_pair.c index d12e135e..769b99fa 100644 --- a/tests/compat_pair.c +++ b/tests/compat_pair.c @@ -20,7 +20,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" diff --git a/tests/compat_pipeline.c b/tests/compat_pipeline.c index 4ed58af7..2e5b0de9 100644 --- a/tests/compat_pipeline.c +++ b/tests/compat_pipeline.c @@ -21,7 +21,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" #define SOCKET_ADDRESS "inproc://a" diff --git a/tests/compat_reqrep.c b/tests/compat_reqrep.c index 046955cf..79bb74bb 100644 --- a/tests/compat_reqrep.c +++ b/tests/compat_reqrep.c @@ -1,7 +1,7 @@ /* Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright 2017 Garrett D'Amore - Copyright 2017 Capitar IT Group BV + Copyright 2018 Staysail Systems, Inc. + Copyright 2018 Capitar IT Group BV Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -22,7 +22,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" diff --git a/tests/compat_reqttl.c b/tests/compat_reqttl.c index c758f92e..84c73e09 100644 --- a/tests/compat_reqttl.c +++ b/tests/compat_reqttl.c @@ -2,7 +2,7 @@ Copyright (c) 2012 Martin Sustrik All rights reserved. Copyright (c) 2013 GoPivotal, Inc. All rights reserved. Copyright 2016 Franklin "Snaipe" Mathieu - Copyright 2017 Garrett D'Amore + Copyright 2018 Garrett D'Amore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" diff --git a/tests/compat_shutdown.c b/tests/compat_shutdown.c index 834eacee..6d078ee2 100644 --- a/tests/compat_shutdown.c +++ b/tests/compat_shutdown.c @@ -21,7 +21,7 @@ IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" int main (int argc, const char *argv[]) diff --git a/tests/compat_survey.c b/tests/compat_survey.c index fc5f8091..30b7ae68 100644 --- a/tests/compat_survey.c +++ b/tests/compat_survey.c @@ -21,7 +21,7 @@ DEALINGS IN THE SOFTWARE. */ -#include "nng_compat.h" +#include #include "compat_testutil.h" diff --git a/tests/compat_testutil.c b/tests/compat_testutil.c index e24f31fc..ef17cb3f 100644 --- a/tests/compat_testutil.c +++ b/tests/compat_testutil.c @@ -32,8 +32,8 @@ #include #include +#include #include "compat_testutil.h" -#include "nng_compat.h" int test_socket_impl(char *file, int line, int family, int protocol); int test_connect_impl(char *file, int line, int sock, char *address); @@ -226,4 +226,4 @@ void nn_sleep(int ms) { nng_msleep(ms); -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2