1 // 2 // Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> 3 // Copyright 2018 Capitar IT Group BV <info@capitar.com> 4 // 5 // This software is supplied under the terms of the MIT License, a 6 // copy of which should be located in the distribution where this 7 // file was obtained (LICENSE.txt). A copy of the license may also be 8 // found online at https://opensource.org/licenses/MIT. 9 // 10 11 #ifndef NNG_COMPAT_NN_H 12 #define NNG_COMPAT_NN_H 13 14 // This header contains interfaces that are intended to offer compatibility 15 // with nanomsg v1.0. These are not the "preferred" interfaces for nng, 16 // and consumers should only use these if they are porting software that 17 // previously used nanomsg. New programs should use the nng native APIs. 18 19 // Note that compatibility promises are limited to public portions of the 20 // nanomsg API, and specifically do NOT extend to the ABI. Furthermore, 21 // there may be other limitations around less commonly used portions of the 22 // API; for example only SP headers may be transported in control data for 23 // messages, there is almost no compatibility offered for statistics. 24 // Error values may differ from those returned by nanomsg as well; the nng 25 // error reporting facility expresses only a subset of the possibilities of 26 // nanomsg. 27 28 // Note that unlike nanomsg, nng does not aggressively recycle socket or 29 // endpoint IDs, which means applications which made assumptions that these 30 // would be relatively small integers (e.g. to use them as array indices) 31 // may break. (No promise about values was ever made.) 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <errno.h> 38 #include <stddef.h> 39 #include <stdint.h> 40 41 // clang-format gets in the way of most of this file. 42 // We turn it off, at least until it gets smarter about aligning 43 // macro definitions or we adopt enums or somesuch. 44 // clang-format off 45 46 // NNG_DECL is used on declarations to deal with scope. 47 // For building Windows DLLs, it should be the appropriate __declspec(). 48 // For shared libraries with platforms that support hidden visibility, 49 // it should evaluate to __attribute__((visibility("default"))). 50 #ifndef NN_DECL 51 #if defined(_WIN32) && !defined(NNG_STATIC_LIB) 52 #if defined(NNG_SHARED_LIB) 53 #define NN_DECL __declspec(dllexport) 54 #else 55 #define NN_DECL __declspec(dllimport) 56 #endif // NNG_SHARED_LIB 57 #else 58 #if defined(NNG_SHARED_LIB) && defined(NNG_HIDDEN_VISIBILITY) 59 #define NN_DECL __attribute__((visibility("default"))) 60 #else 61 #define NN_DECL extern 62 #endif 63 #endif // _WIN32 && !NNG_STATIC_LIB 64 #endif // NN_DECL 65 66 #define AF_SP 1 67 #define AF_SP_RAW 2 68 69 #define NN_SOCKADDR_MAX 128 70 #define NN_SOL_SOCKET 0 71 72 // Flag for send/recv (nonblocking) 73 #define NN_DONTWAIT 1 74 75 // CMSG data type 76 #define PROTO_SP 1 77 #define SP_HDR 1 78 79 // Errnos. Legacy nanomsg uses posix errnos where possible. 80 // If a define is not set, use add NN_ERRBASE. nng does not 81 // return all of these values, so there may be some loss of 82 // of information for edge cases, but we don't expect that to be 83 // a problem really. 84 #define NN_ERRBASE (0x10000000) 85 #ifndef ENOTSUP 86 #define ENOTSUP (NN_ERRBASE+1) 87 #endif 88 #ifndef EPROTONOSUPPORT 89 #define EPROTONOSUPPORT (NN_ERRBASE+2) 90 #endif 91 #ifndef ENOBUFS 92 #define ENOBUFS (NN_ERRBASE+3) 93 #endif 94 #ifndef ENETDOWN 95 #define ENETDOWN (NN_ERRBASE+4) 96 #endif 97 #ifndef EADDRINUSE 98 #define EADDRINUSE (NN_ERRBASE+5) 99 #endif 100 #ifndef EADDRNOTAVAIL 101 #define EADDRNOTAVAIL (NN_ERRBASE+6) 102 #endif 103 #ifndef ENOTSOCK 104 #define ENOTSOCK (NN_ERRBASE+7) 105 #endif 106 #ifndef EAGAIN 107 #define EAGAIN (NN_ERRBASE+8) 108 #endif 109 #ifndef EBADF 110 #define EBADF (NN_ERRBASE+9) 111 #endif 112 #ifndef EINVAL 113 #define EINVAL (NN_ERRBASE+10) 114 #endif 115 #ifndef EMFILE 116 #define EMFILE (NN_ERRBASE+11) 117 #endif 118 #ifndef EFAULT 119 #define EFAULT (NN_ERRBASE+12) 120 #endif 121 #ifndef EACCES 122 #define EACCES (NN_ERRBASE+13) 123 #endif 124 #ifndef ENETRESET 125 #define ENETRESET (NN_ERRBASE+14) 126 #endif 127 #ifndef ENETUNREACH 128 #define ENETUNREACH (NN_ERRBASE+15) 129 #endif 130 #ifndef EHOSTUNREACH 131 #define EHOSTUNREACH (NN_ERRBASE+16) 132 #endif 133 #ifndef EAFNOSUPPORT 134 #define EAFNOSUPPORT (NN_ERRBASE+17) 135 #endif 136 #ifndef EINPROGRESS 137 #define EINPROGRESS (NN_ERRBASE+18) 138 #endif 139 #ifndef EPROTO 140 #define EPROTO (NN_ERRBASE+19) 141 #endif 142 #ifndef ECONNREFUSED 143 #define ECONNREFUSED (NN_ERRBASE+20) 144 #endif 145 #ifndef ENOTCONN 146 #define ENOTCONN (NN_ERRBASE+21) 147 #endif 148 #ifndef EMSGSIZE 149 #define EMSGSIZE (NN_ERRBASE+22) 150 #endif 151 #ifndef ETIMEDOUT 152 #define ETIMEDOUT (NN_ERRBASE+23) 153 #endif 154 #ifndef ECONNABORTED 155 #define ECONNABORTED (NN_ERRBASE+24) 156 #endif 157 #ifndef ECONNRESET 158 #define ECONNRESET (NN_ERRBASE+25) 159 #endif 160 #ifndef ENOPROTOOPT 161 #define ENOPROTOOPT (NN_ERRBASE+26) 162 #endif 163 #ifndef EISCONN 164 #define EISCONN (NN_ERRBASE+27) 165 #endif 166 #ifndef ESOCKNOSUPPORT 167 #define ESOCKNOSPPORT (NN_ERRBASE+28) 168 #endif 169 #ifndef ETERM 170 #define ETERM (NN_ERRBASE+29) 171 #endif 172 #ifndef EFSM 173 #define EFSM (NN_ERRBASE+30) 174 #endif 175 #ifndef ENOENT 176 #define ENOENT (NN_ERRBASE+31) 177 #endif 178 #ifndef EIO 179 #define EIO (NN_ERRBASE+32) 180 #endif 181 #ifndef EEXIST 182 #define EEXIST (NN_ERRBASE+33) 183 #endif 184 #ifndef ENOSPC 185 #define ENOSPC (NN_ERRBASE+34) 186 #endif 187 188 189 // Socket options 190 #define NN_LINGER 1 191 #define NN_SNDBUF 2 192 #define NN_RCVBUF 3 193 #define NN_SNDTIMEO 4 194 #define NN_RCVTIMEO 5 195 #define NN_RECONNECT_IVL 6 196 #define NN_RECONNECT_IVL_MAX 7 197 #define NN_SNDPRIO 8 198 #define NN_RCVPRIO 9 199 #define NN_SNDFD 10 200 #define NN_RCVFD 11 201 #define NN_DOMAIN 12 202 #define NN_PROTOCOL 13 203 #define NN_IPV4ONLY 14 204 #define NN_SOCKET_NAME 15 205 #define NN_RCVMAXSIZE 16 206 #define NN_MAXTTL 17 207 208 // from this point on formatting is fine 209 // clang-format on 210 211 // Poll stuff 212 #define NN_POLLIN 1 213 #define NN_POLLOUT 2 214 struct nn_pollfd { 215 int fd; 216 uint16_t events; 217 uint16_t revents; 218 }; 219 220 // Magical size for allocation 221 #define NN_MSG ((size_t) -1) 222 223 struct nn_iovec { 224 void * iov_base; 225 size_t iov_len; 226 }; 227 228 struct nn_msghdr { 229 struct nn_iovec *msg_iov; 230 int msg_iovlen; 231 void * msg_control; 232 size_t msg_controllen; 233 }; 234 235 struct nn_cmsghdr { 236 size_t cmsg_len; 237 int cmsg_level; 238 int cmsg_type; 239 }; 240 241 #define NN_CMSG_ALIGN(len) \ 242 (((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1)) 243 244 // Unlike old nanomsg, we explicitly only support the SP header as attached 245 // cmsg data. It turns out that old nanomsg didn't really store anything 246 // useful otherwise anyway. (One specific exception was that it stored the 247 // message type of text or binary for the websocket transport. We don't think 248 // anyone used that in practice though.) 249 #define NN_CMSG_FIRSTHDR(mh) nn_cmsg_next((struct nn_msghdr *) (mh), NULL) 250 #define NN_CMSG_NXTHDR(mh, ch) \ 251 nn_cmsg_next((struct nn_msghdr *) (mh), (struct nn_cmsghdr *) ch) 252 #define NN_CMSG_DATA(ch) ((unsigned char *) (((struct nn_cmsghdr *) (ch)) + 1)) 253 #define NN_CMSG_SPACE(len) \ 254 (NN_CMSG_ALIGN(len) + NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr))) 255 #define NN_CMSG_LEN(len) (NN_CMSG_ALIGN(sizeof(struct nn_cmsghdr)) + (len)) 256 257 NN_DECL struct nn_cmsghdr *nn_cmsg_next( 258 struct nn_msghdr *, struct nn_cmsghdr *); 259 NN_DECL int nn_socket(int, int); 260 NN_DECL int nn_setsockopt(int, int, int, const void *, size_t); 261 NN_DECL int nn_getsockopt(int, int, int, void *, size_t *); 262 NN_DECL int nn_bind(int, const char *); 263 NN_DECL int nn_connect(int, const char *); 264 NN_DECL int nn_shutdown(int, int); 265 NN_DECL int nn_send(int, const void *, size_t, int); 266 NN_DECL int nn_recv(int, void *, size_t, int); 267 NN_DECL int nn_sendmsg(int, const struct nn_msghdr *, int); 268 NN_DECL int nn_recvmsg(int, struct nn_msghdr *, int); 269 NN_DECL int nn_close(int); 270 NN_DECL int nn_poll(struct nn_pollfd *, int, int); 271 NN_DECL int nn_device(int, int); 272 NN_DECL uint64_t nn_get_statistic(int, int); 273 NN_DECL void * nn_allocmsg(size_t, int); 274 NN_DECL void * nn_reallocmsg(void *, size_t); 275 NN_DECL int nn_freemsg(void *); 276 NN_DECL int nn_errno(void); 277 NN_DECL const char *nn_strerror(int); 278 NN_DECL void nn_term(void); 279 280 #ifdef __cplusplus 281 } 282 #endif 283 284 #endif // NNG_COMPAT_NN_H 285