1 module libnng.libnng;
2 
3 import std.meta : Alias;
4 import core.stdc.config;
5 import std.traits;
6 import core.stdc.stdio : printf;
7 
8 alias nng_cb = void function(void*);
9 alias nng_aio_cancel_cb = void function(nng_aio*, void*, int);
10 alias nng_pipe_notify_cb = void function(nng_pipe, nng_pipe_ev, void*) nothrow;
11 alias nng_http_cb = void function(nng_aio*);
12 
13 @safe:
14 
15 @nogc nothrow extern (C) {
16 
17     enum NNG_MAJOR_VERSION = 1;
18     enum NNG_MINOR_VERSION = 6;
19     enum NNG_PATCH_VERSION = 0;
20 
21     const int NNG_MAXADDRLEN = 128;
22 
23     int NNG_PROTOCOL_NUMBER(int maj, int min) {
24         return maj * 16 + min;
25     }
26 
27     enum nng_errno : int {
28         @("Ok!") NNG_OK = 0,
29         @("Interrupted system call") NNG_EINTR = 1,
30         @("Insufficient free memory exists.") NNG_ENOMEM = 2,
31         @("An invalid URL or other data was supplied.") NNG_EINVAL = 3,
32         @("Server instance is running.") NNG_EBUSY = 4,
33         @("The operation timed out.") NNG_ETIMEDOUT = 5,
34         @("The remote peer refused the connection.") NNG_ECONNREFUSED = 6,
35         @("At least one of the sockets is not open.") NNG_ECLOSED = 7,
36         @("Resource temporarily unavailable") NNG_EAGAIN = 8,
37         @("The option or protocol is not supported.") NNG_ENOTSUP = 9,
38         @("The address is already in use.") NNG_EADDRINUSE = 10,
39         @("The context/dialer/listener cannot do what your want state.") NNG_ESTATE = 11,
40         @("Handler is not registered with server.") NNG_ENOENT = 12,
41         @("A protocol error occurred.") NNG_EPROTO = 13,
42         @("The remote address is not reachable.") NNG_EUNREACHABLE = 14,
43         @("The address is invalid or unavailable.") NNG_EADDRINVAL = 15,
44         @("No permission to read the file.") NNG_EPERM = 16,
45         @("The message is too large.") NNG_EMSGSIZE = 17,
46         @("Software caused connection abort") NNG_ECONNABORTED = 18,
47         @("The connection was reset by the peer.") NNG_ECONNRESET = 19,
48         @("The operation was aborted.") NNG_ECANCELED = 20,
49         @("") NNG_ENOFILES = 21,
50         @("No space left on device") NNG_ENOSPC = 22,
51         @("") NNG_EEXIST = 23,
52         @("The option may not be modified.") NNG_EREADONLY = 24,
53         @("The option may not read.") NNG_EWRITEONLY = 25,
54         @("") NNG_ECRYPTO = 26,
55         @("Authentication or authorization failure.") NNG_EPEERAUTH = 27,
56         @("Option requires an argument: but one is not present.") NNG_ENOARG = 28,
57         @("Parsed option matches more than one specification.") NNG_EAMBIGUOUS = 29,
58         @("Incorrect type for option.") NNG_EBADTYPE = 30,
59         @("Remote peer shutdown after sending data.") NNG_ECONNSHUT = 31,
60         @("") NNG_EINTERNAL = 1000,
61         @("") NNG_ESYSERR = 0x1000_0000,
62         @("") NNG_ETRANERR = 0x2000_0000,
63     }
64 
65     string nng_errstr(int err) {
66         nng_errno errno = cast(nng_errno) err;
67         switch (errno) {
68             static foreach (E; EnumMembers!nng_errno) {
69         case E:
70                 enum error_text = getUDAs!(E, string)[0];
71                 return (error_text.length) ? error_text : E.stringof;
72             }
73         default:
74             return null;
75         }
76         assert(0);
77     }
78 
79     enum nng_flag {
80         NNG_FLAG_ALLOC = 1,
81         NNG_FLAG_NONBLOCK = 2
82     }
83 
84     T* ptr(T)(T[] arr) {
85         return arr.length == 0 ? null : &arr[0];
86     }
87 
88     // ------------------------------------- typedefs
89 
90     struct nng_ctx {
91         uint id;
92     };
93     struct nng_dialer {
94         uint id;
95     };
96     struct nng_listener {
97         uint id;
98     };
99     struct nng_pipe {
100         uint id;
101     };
102     struct nng_socket {
103         uint id;
104     };
105 
106     alias nng_duration = int;
107 
108     struct nng_msg {
109     };
110     struct nng_stat {
111     };
112     struct nng_aio {
113     };
114 
115     alias NNG_PIPE_INITIALIZER = Alias!(nng_pipe(0));
116     alias NNG_SOCKET_INITIALIZER = Alias!(nng_socket(0));
117     alias NNG_DIALER_INITIALIZER = Alias!(nng_socket(0));
118     alias NNG_LISTENER_INITIALIZER = Alias!(nng_socket(0));
119     alias NNG_CTX_INITIALIZER = Alias!(nng_socket(0));
120 
121     alias NNG_DURATION_INFINITE = Alias!(nng_duration(-1));
122     alias NNG_DURATION_DEFAULT = Alias!(nng_duration(-2));
123     alias NNG_DURATION_ZERO = Alias!(nng_duration(0));
124 
125     struct nng_sockaddr_inproc {
126         ushort sa_family;
127         char[NNG_MAXADDRLEN] sa_name;
128     };
129 
130     struct nng_sockaddr_path {
131         ushort sa_family;
132         char[NNG_MAXADDRLEN] sa_path;
133     };
134 
135     alias nng_sockaddr_ipc = nng_sockaddr_path;
136 
137     struct nng_sockaddr_in6 {
138         ushort sa_family;
139         ushort sa_port;
140         ubyte[16] sa_addr;
141         uint sa_scope;
142     };
143 
144     struct nng_sockaddr_in {
145         ushort sa_family;
146         ushort sa_port;
147         uint sa_addr;
148     };
149 
150     struct nng_sockaddr_zt {
151         ushort sa_family;
152         ulong sa_nwid;
153         ulong sa_nodeid;
154         uint sa_port;
155     };
156 
157     struct nng_sockaddr_abstract {
158         ushort sa_family;
159         ushort sa_len; // will be 0 - 107 max.
160         ubyte[107] sa_name; // 108 linux/windows, without leading NUL
161     };
162 
163     struct nng_sockaddr_storage {
164         ushort sa_family;
165         ulong[16] sa_pad;
166     };
167 
168     union nng_sockaddr {
169         ushort s_family;
170         nng_sockaddr_ipc s_ipc;
171         nng_sockaddr_inproc s_inproc;
172         nng_sockaddr_in6 s_in6;
173         nng_sockaddr_in s_in;
174         nng_sockaddr_zt s_zt;
175         nng_sockaddr_abstract s_abstract;
176         nng_sockaddr_storage s_storage;
177     };
178     enum nng_sockaddr_family {
179         NNG_AF_NONE = 65535,
180         NNG_AF_UNSPEC = 0,
181         NNG_AF_INPROC = 1,
182         NNG_AF_IPC = 2,
183         NNG_AF_INET = 3,
184         NNG_AF_INET6 = 4,
185         NNG_AF_ZT = 5, // ZeroTier
186         NNG_AF_ABSTRACT = 6
187     };
188 
189     struct nng_iov {
190         void* iov_buf;
191         size_t iov_len;
192     };
193 
194     // ------------------------------------- common functions
195 
196     void nng_fini();
197     void* nng_alloc(size_t);
198     void nng_free(void*, size_t);
199     char* nng_strdup(const char*);
200     char* nng_strerror(int);
201     void nng_strfree(char*);
202     char* nng_version() pure;
203 
204     // ------------------------------------- system functions
205 
206     alias nng_time = ulong;
207     struct nng_thread {
208     };
209     struct nng_mtx {
210     };
211     struct nng_cv {
212     };
213 
214     nng_time nng_clock();
215     void nng_msleep(nng_duration);
216     int nng_thread_create(nng_thread**, nng_cb, void*);
217     void nng_thread_set_name(nng_thread*, const char*);
218     void nng_thread_destroy(nng_thread*);
219     int nng_mtx_alloc(nng_mtx**);
220     void nng_mtx_free(nng_mtx*);
221     void nng_mtx_lock(nng_mtx*);
222     void nng_mtx_unlock(nng_mtx*);
223     int nng_cv_alloc(nng_cv**, nng_mtx*);
224     void nng_cv_free(nng_cv*);
225     void nng_cv_wait(nng_cv*);
226     int nng_cv_until(nng_cv*, nng_time);
227     void nng_cv_wake(nng_cv*);
228     void nng_cv_wake1(nng_cv*);
229     uint nng_random();
230 
231     // ------------------------------------- opt functions
232 
233     const string NNG_OPT_SOCKNAME = "socket-name"; // string 
234     const string NNG_OPT_RAW = "raw"; // bool
235     const string NNG_OPT_PROTO = "protocol"; // int:enum:NNG_*_(SELF|PEER)
236     const string NNG_OPT_PROTONAME = "protocol-name"; // string
237     const string NNG_OPT_PEER = "peer"; // int:enum:NNG_*_(SELF|PEER)_NAME
238     const string NNG_OPT_PEERNAME = "peer-name"; // string
239     const string NNG_OPT_RECVBUF = "recv-buffer"; // int
240     const string NNG_OPT_SENDBUF = "send-buffer"; // int
241     const string NNG_OPT_RECVFD = "recv-fd"; // int:fd:(ro)
242     const string NNG_OPT_SENDFD = "send-fd"; // int:fd:(ro)
243     const string NNG_OPT_RECVTIMEO = "recv-timeout"; // int:ms 
244     const string NNG_OPT_SENDTIMEO = "send-timeout"; // int:ms
245     const string NNG_OPT_LOCADDR = "local-address"; // for:nng_*_get_addr:nng_sockaddr/listener
246     const string NNG_OPT_REMADDR = "remote-address"; // for:nng_*_get_addr:nng_sockaddr/listener
247     const string NNG_OPT_URL = "url"; // for:nng_*_get_string:string/listener
248     const string NNG_OPT_MAXTTL = "ttl-max"; // int:ms
249     const string NNG_OPT_RECVMAXSZ = "recv-size-max"; // int
250     const string NNG_OPT_RECONNMINT = "reconnect-time-min"; // int:ms
251     const string NNG_OPT_RECONNMAXT = "reconnect-time-max"; // int:ms
252     const string NNG_OPT_TLS_CONFIG = "tls-config"; // TODO:
253     const string NNG_OPT_TLS_AUTH_MODE = "tls-authmode"; // TODO:
254     const string NNG_OPT_TLS_CERT_KEY_FILE = "tls-cert-key-file"; // TODO:
255     const string NNG_OPT_TLS_CA_FILE = "tls-ca-file"; // TODO:
256     const string NNG_OPT_TLS_SERVER_NAME = "tls-server-name"; // TODO:
257     const string NNG_OPT_TLS_VERIFIED = "tls-verified"; // TODO:
258     const string NNG_OPT_TLS_PEER_CN = "tls-peer-cn"; // TODO:
259     const string NNG_OPT_TLS_PEER_ALT_NAMES = "tls-peer-alt-names"; // TODO:
260     const string NNG_OPT_TCP_NODELAY = "tcp-nodelay"; // bool
261     const string NNG_OPT_TCP_KEEPALIVE = "tcp-keepalive"; // bool, int???
262     const string NNG_OPT_TCP_BOUND_PORT = "tcp-bound-port"; // int:(ro)
263     const string NNG_OPT_IPC_SECURITY_DESCRIPTOR = "ipc:security-descriptor"; // for:nng_stream_listener:ptr
264     const string NNG_OPT_IPC_PERMISSIONS = "ipc:permissions"; // int:(ro)
265     const string NNG_OPT_IPC_PEER_UID = "ipc:peer-uid"; // int:(ro) 
266     const string NNG_OPT_IPC_PEER_GID = "ipc:peer-gid"; // int:(ro)
267     const string NNG_OPT_IPC_PEER_PID = "ipc:peer-pid"; // int:(ro)
268     const string NNG_OPT_IPC_PEER_ZONEID = "ipc:peer-zoneid"; // int:(ro)
269     const string NNG_OPT_WS_REQUEST_HEADERS = "ws:request-headers"; // TODO:
270     const string NNG_OPT_WS_RESPONSE_HEADERS = "ws:response-headers"; // TODO:
271     const string NNG_OPT_WS_RESPONSE_HEADER = "ws:response-header:"; // TODO:
272     const string NNG_OPT_WS_REQUEST_HEADER = "ws:request-header:"; // TODO:
273     const string NNG_OPT_WS_REQUEST_URI = "ws:request-uri"; // TODO:
274     const string NNG_OPT_WS_SENDMAXFRAME = "ws:txframe-max"; // TODO:
275     const string NNG_OPT_WS_RECVMAXFRAME = "ws:rxframe-max"; // TODO:
276     const string NNG_OPT_WS_PROTOCOL = "ws:protocol"; // TODO:
277     const string NNG_OPT_WS_SEND_TEXT = "ws:send-text"; // TODO:
278     const string NNG_OPT_WS_RECV_TEXT = "ws:recv-text"; // TODO:
279 
280     struct nng_optspec {
281         const char* o_name; // Long style name (may be NULL for short only)
282         int o_short; // Short option (no clustering!)
283         int o_val; // Value stored on a good parse (>0)
284         bool o_arg; // Option takes an argument if true
285     };
286 
287     int nng_opts_parse(int argc, const char** argv,
288             const nng_optspec* opts, int* val, char** optarg, int* optidx);
289 
290     // ------------------------------------- aio functions:
291 
292     int nng_aio_alloc(nng_aio**, nng_cb, void*);
293     void nng_aio_free(nng_aio*);
294     void nng_aio_reap(nng_aio*);
295     void nng_aio_stop(nng_aio*);
296     int nng_aio_result(nng_aio*);
297     size_t nng_aio_count(nng_aio*);
298     void nng_aio_cancel(nng_aio*);
299     void nng_aio_abort(nng_aio*, int);
300     void nng_aio_wait(nng_aio*);
301     bool nng_aio_busy(nng_aio*);
302     void nng_aio_set_msg(nng_aio*, nng_msg*);
303     nng_msg* nng_aio_get_msg(nng_aio*);
304     int nng_aio_set_input(nng_aio*, uint, void*);
305     void* nng_aio_get_input(nng_aio*, uint);
306     int nng_aio_set_output(nng_aio*, uint, void*);
307     void* nng_aio_get_output(nng_aio*, uint);
308     void nng_aio_set_timeout(nng_aio*, nng_duration);
309     int nng_aio_set_iov(nng_aio*, uint, const nng_iov*);
310     bool nng_aio_begin(nng_aio*);
311     void nng_aio_finish(nng_aio*, int);
312     void nng_aio_defer(nng_aio*, nng_aio_cancel_cb, void*);
313     void nng_sleep_aio(nng_duration, nng_aio*);
314 
315     // ------------------------------------- context functions
316 
317     int nng_ctx_open(nng_ctx*, nng_socket);
318     int nng_ctx_close(nng_ctx);
319     int nng_ctx_id(nng_ctx);
320     int nng_ctx_recvmsg(nng_ctx, nng_msg**, int);
321     int nng_ctx_sendmsg(nng_ctx, nng_msg*, int);
322 
323     int nng_ctx_get(nng_ctx, const char*, void*, size_t*);
324     int nng_ctx_get_bool(nng_ctx, const char*, bool*);
325     int nng_ctx_get_int(nng_ctx, const char*, int*);
326     int nng_ctx_get_size(nng_ctx, const char*, size_t*);
327     int nng_ctx_get_uint64(nng_ctx, const char*, ulong*);
328     int nng_ctx_get_string(nng_ctx, const char*, char**);
329     int nng_ctx_get_ptr(nng_ctx, const char*, void**);
330     int nng_ctx_get_ms(nng_ctx, const char*, nng_duration*);
331     int nng_ctx_get_addr(nng_ctx, const char*, nng_sockaddr*);
332 
333     int nng_ctx_set(nng_ctx, const char*, const void*, size_t);
334     int nng_ctx_set_bool(nng_ctx, const char*, bool);
335     int nng_ctx_set_int(nng_ctx, const char*, int);
336     int nng_ctx_set_size(nng_ctx, const char*, size_t);
337     int nng_ctx_set_uint64(nng_ctx, const char*, ulong);
338     int nng_ctx_set_string(nng_ctx, const char*, const char*);
339     int nng_ctx_set_ptr(nng_ctx, const char*, void*);
340     int nng_ctx_set_ms(nng_ctx, const char*, nng_duration);
341     int nng_ctx_set_addr(nng_ctx, const char*, const nng_sockaddr*);
342     void nng_ctx_recv(nng_ctx, nng_aio*);
343     void nng_ctx_send(nng_ctx, nng_aio*);
344 
345     // ------------------------------------- device functions 
346     int nng_device(nng_socket, nng_socket);
347     void nng_device_aio(nng_aio*, nng_socket, nng_socket);
348 
349     // ------------------------------------- statistics functions TODO:
350 
351     // ------------------------------------- socket functions
352 
353     int nng_close(nng_socket);
354     int nng_socket_id(nng_socket);
355 
356     int nng_socket_set(nng_socket, const char*, const void*, size_t);
357     int nng_socket_set_bool(nng_socket, const char*, bool);
358     int nng_socket_set_int(nng_socket, const char*, int);
359     int nng_socket_set_size(nng_socket, const char*, size_t);
360     int nng_socket_set_uint64(nng_socket, const char*, ulong);
361     int nng_socket_set_string(nng_socket, const char*, const char*);
362     int nng_socket_set_ptr(nng_socket, const char*, void*);
363     int nng_socket_set_ms(nng_socket, const char*, nng_duration);
364     int nng_socket_set_addr(nng_socket, const char*, const nng_sockaddr*);
365 
366     int nng_socket_get(nng_socket, const char*, void*, size_t*);
367     int nng_socket_get_bool(nng_socket, const char*, bool*);
368     int nng_socket_get_int(nng_socket, const char*, int*);
369     int nng_socket_get_size(nng_socket, const char*, size_t*);
370     int nng_socket_get_uint64(nng_socket, const char*, ulong*);
371     int nng_socket_get_string(nng_socket, const char*, char**);
372     int nng_socket_get_ptr(nng_socket, const char*, void**);
373     int nng_socket_get_ms(nng_socket, const char*, nng_duration*);
374     int nng_socket_get_addr(nng_socket, const char*, nng_sockaddr*);
375 
376     enum nng_pipe_ev {
377         NNG_PIPE_EV_ADD_PRE, // Called just before pipe added to socket
378         NNG_PIPE_EV_ADD_POST, // Called just after pipe added to socket
379         NNG_PIPE_EV_REM_POST, // Called just after pipe removed from socket
380         NNG_PIPE_EV_NUM, // Used internally, must be last.
381     }
382 
383     int nng_pipe_notify(nng_socket, nng_pipe_ev, nng_pipe_notify_cb, void*);
384 
385     int nng_dial(nng_socket, const char*, nng_dialer*, int);
386     int nng_dialer_create(nng_dialer*, nng_socket, const char*);
387     int nng_dialer_start(nng_dialer, int);
388     int nng_dialer_close(nng_dialer);
389     int nng_dialer_id(nng_dialer);
390 
391     int nng_dialer_set(nng_dialer, const char*, const void*, size_t);
392     int nng_dialer_set_bool(nng_dialer, const char*, bool);
393     int nng_dialer_set_int(nng_dialer, const char*, int);
394     int nng_dialer_set_size(nng_dialer, const char*, size_t);
395     int nng_dialer_set_uint64(nng_dialer, const char*, ulong);
396     int nng_dialer_set_string(nng_dialer, const char*, const char*);
397     int nng_dialer_set_ptr(nng_dialer, const char*, void*);
398     int nng_dialer_set_ms(nng_dialer, const char*, nng_duration);
399     int nng_dialer_set_addr(nng_dialer, const char*, const nng_sockaddr*);
400 
401     int nng_dialer_get(nng_dialer, const char*, void*, size_t*);
402     int nng_dialer_get_bool(nng_dialer, const char*, bool*);
403     int nng_dialer_get_int(nng_dialer, const char*, int*);
404     int nng_dialer_get_size(nng_dialer, const char*, size_t*);
405     int nng_dialer_get_uint64(nng_dialer, const char*, ulong*);
406     int nng_dialer_get_string(nng_dialer, const char*, char**);
407     int nng_dialer_get_ptr(nng_dialer, const char*, void**);
408     int nng_dialer_get_ms(nng_dialer, const char*, nng_duration*);
409     int nng_dialer_get_addr(nng_dialer, const char*, nng_sockaddr*);
410 
411     int nng_listen(nng_socket, const char*, nng_listener*, int);
412     int nng_listener_create(nng_listener*, nng_socket, const char*);
413     int nng_listener_start(nng_listener, int);
414     int nng_listener_close(nng_listener);
415     int nng_listener_id(nng_listener);
416 
417     int nng_listener_set(nng_listener, const char*, const void*, size_t);
418     int nng_listener_set_bool(nng_listener, const char*, bool);
419     int nng_listener_set_int(nng_listener, const char*, int);
420     int nng_listener_set_size(nng_listener, const char*, size_t);
421     int nng_listener_set_uint64(nng_listener, const char*, ulong);
422     int nng_listener_set_string(nng_listener, const char*, const char*);
423     int nng_listener_set_ptr(nng_listener, const char*, void*);
424     int nng_listener_set_ms(nng_listener, const char*, nng_duration);
425     int nng_listener_set_addr(nng_listener, const char*, const nng_sockaddr*);
426 
427     int nng_listener_get(nng_listener, const char*, void*, size_t*);
428     int nng_listener_get_bool(nng_listener, const char*, bool*);
429     int nng_listener_get_int(nng_listener, const char*, int*);
430     int nng_listener_get_size(nng_listener, const char*, size_t*);
431     int nng_listener_get_uint64(nng_listener, const char*, ulong*);
432     int nng_listener_get_string(nng_listener, const char*, char**);
433     int nng_listener_get_ptr(nng_listener, const char*, void**);
434     int nng_listener_get_ms(nng_listener, const char*, nng_duration*);
435     int nng_listener_get_addr(nng_listener, const char*, nng_sockaddr*);
436 
437     int nng_send(nng_socket, void*, size_t, int);
438     int nng_recv(nng_socket, void*, size_t*, int);
439     int nng_sendmsg(nng_socket, nng_msg*, int);
440     int nng_recvmsg(nng_socket, nng_msg**, int);
441     void nng_send_aio(nng_socket, nng_aio*);
442     void nng_recv_aio(nng_socket, nng_aio*);
443 
444     // ------------------------------------- message functions
445 
446     int nng_msg_alloc(nng_msg**, size_t);
447     void nng_msg_free(nng_msg*);
448     int nng_msg_realloc(nng_msg*, size_t);
449     int nng_msg_reserve(nng_msg*, size_t);
450     size_t nng_msg_capacity(nng_msg*);
451     void* nng_msg_header(nng_msg*);
452     size_t nng_msg_header_len(const nng_msg*);
453     void* nng_msg_body(nng_msg*);
454     size_t nng_msg_len(const nng_msg*);
455     int nng_msg_append(nng_msg*, const void*, size_t);
456     int nng_msg_insert(nng_msg*, const void*, size_t);
457     int nng_msg_trim(nng_msg*, size_t);
458     int nng_msg_chop(nng_msg*, size_t);
459     int nng_msg_header_append(nng_msg*, const void*, size_t);
460     int nng_msg_header_insert(nng_msg*, const void*, size_t);
461     int nng_msg_header_trim(nng_msg*, size_t);
462     int nng_msg_header_chop(nng_msg*, size_t);
463     int nng_msg_header_append_u16(nng_msg*, ushort);
464     int nng_msg_header_append_u32(nng_msg*, uint);
465     int nng_msg_header_append_u64(nng_msg*, ulong);
466     int nng_msg_header_insert_u16(nng_msg*, ushort);
467     int nng_msg_header_insert_u32(nng_msg*, uint);
468     int nng_msg_header_insert_u64(nng_msg*, ulong);
469     int nng_msg_header_chop_u16(nng_msg*, ushort*);
470     int nng_msg_header_chop_u32(nng_msg*, uint*);
471     int nng_msg_header_chop_u64(nng_msg*, ulong*);
472     int nng_msg_header_trim_u16(nng_msg*, ushort*);
473     int nng_msg_header_trim_u32(nng_msg*, uint*);
474     int nng_msg_header_trim_u64(nng_msg*, ulong*);
475     int nng_msg_append_u16(nng_msg*, ushort);
476     int nng_msg_append_u32(nng_msg*, uint);
477     int nng_msg_append_u64(nng_msg*, ulong);
478     int nng_msg_insert_u16(nng_msg*, ushort);
479     int nng_msg_insert_u32(nng_msg*, uint);
480     int nng_msg_insert_u64(nng_msg*, ulong);
481     int nng_msg_chop_u16(nng_msg*, ushort*);
482     int nng_msg_chop_u32(nng_msg*, uint*);
483     int nng_msg_chop_u64(nng_msg*, ulong*);
484     int nng_msg_trim_u16(nng_msg*, ushort*);
485     int nng_msg_trim_u32(nng_msg*, uint*);
486     int nng_msg_trim_u64(nng_msg*, ulong*);
487     int nng_msg_dup(nng_msg**, const nng_msg*);
488     void nng_msg_clear(nng_msg*);
489     void nng_msg_header_clear(nng_msg*);
490     void nng_msg_set_pipe(nng_msg*, nng_pipe);
491     nng_pipe nng_msg_get_pipe(const nng_msg*);
492 
493     // ------------------------------------- pipe functions
494 
495     int nng_pipe_get(nng_pipe, const char*, void*, size_t*);
496     int nng_pipe_get_bool(nng_pipe, const char*, bool*);
497     int nng_pipe_get_int(nng_pipe, const char*, int*);
498     int nng_pipe_get_ms(nng_pipe, const char*, nng_duration*);
499     int nng_pipe_get_size(nng_pipe, const char*, size_t*);
500     int nng_pipe_get_uint64(nng_pipe, const char*, ulong*);
501     int nng_pipe_get_string(nng_pipe, const char*, char**);
502     int nng_pipe_get_ptr(nng_pipe, const char*, void**);
503     int nng_pipe_get_addr(nng_pipe, const char*, nng_sockaddr*);
504 
505     int nng_pipe_close(nng_pipe);
506     int nng_pipe_id(nng_pipe);
507     nng_socket nng_pipe_socket(nng_pipe);
508     nng_dialer nng_pipe_dialer(nng_pipe);
509     nng_listener nng_pipe_listener(nng_pipe);
510 
511     // ------------------------------------- stream functions TODO:
512 
513     // ------------------------------------- protocol functions
514 
515     int nng_bus0_open(nng_socket*);
516     int nng_bus0_open_raw(nng_socket*);
517     alias nng_bus_open = nng_bus0_open;
518     alias nng_bus_open_raw = nng_bus0_open_raw;
519 
520     int nng_pair0_open(nng_socket*);
521     int nng_pair0_open_raw(nng_socket*);
522     int nng_pair1_open(nng_socket*);
523     int nng_pair1_open_raw(nng_socket*);
524     int nng_pair1_open_poly(nng_socket*);
525     alias nng_pair_open = nng_pair0_open;
526     alias nng_pair_open_raw = nng_pair0_open_raw;
527 
528     int nng_pull0_open(nng_socket*);
529     int nng_pull0_open_raw(nng_socket*);
530     alias nng_pull_open = nng_pull0_open;
531     alias nng_pull_open_raw = nng_pull0_open_raw;
532 
533     int nng_push0_open(nng_socket*);
534     int nng_push0_open_raw(nng_socket*);
535     alias nng_push_open = nng_push0_open;
536     alias nng_push_open_raw = nng_push0_open_raw;
537 
538     int nng_pub0_open(nng_socket*);
539     int nng_pub0_open_raw(nng_socket*);
540     alias nng_pub_open = nng_pub0_open;
541     alias nng_pub_open_raw = nng_pub0_open_raw;
542 
543     int nng_sub0_open(nng_socket*);
544     int nng_sub0_open_raw(nng_socket*);
545     alias nng_sub_open = nng_sub0_open;
546     alias nng_sub_open_raw = nng_sub0_open_raw;
547 
548     const string NNG_OPT_SUB_SUBSCRIBE = "sub:subscribe";
549     const string NNG_OPT_SUB_UNSUBSCRIBE = "sub:unsubscribe";
550     const string NNG_OPT_SUB_PREFNEW = "sub:prefnew";
551 
552     int nng_req0_open(nng_socket*);
553     int nng_req0_open_raw(nng_socket*);
554     alias nng_req_open = nng_req0_open;
555     alias nng_req_open_raw = nng_req0_open_raw;
556 
557     const string NNG_OPT_REQ_RESENDTIME = "req:resend-time";
558 
559     int nng_rep0_open(nng_socket*);
560     int nng_rep0_open_raw(nng_socket*);
561     alias nng_rep_open = nng_rep0_open;
562     alias nng_rep_open_raw = nng_rep0_open_raw;
563 
564     int nng_surveyor0_open(nng_socket*);
565     int nng_surveyor0_open_raw(nng_socket*);
566     alias nng_surveyor_open = nng_surveyor0_open;
567     alias nng_surveyor_open_raw = nng_surveyor0_open_raw;
568 
569     const string NNG_OPT_SURVEYOR_SURVEYTIME = "surveyor:survey-time";
570 
571     int nng_respondent0_open(nng_socket*);
572     int nng_respondent0_open_raw(nng_socket*);
573     alias nng_respondent_open = nng_respondent0_open;
574     alias nng_respondent_open_raw = nng_respondent0_open_raw;
575 
576     // ------------------------------------- HTTP functions
577 
578     enum nng_http_status {
579         NNG_HTTP_STATUS_CONTINUE = 100,
580         NNG_HTTP_STATUS_SWITCHING = 101,
581         NNG_HTTP_STATUS_PROCESSING = 102,
582         NNG_HTTP_STATUS_OK = 200,
583         NNG_HTTP_STATUS_CREATED = 201,
584         NNG_HTTP_STATUS_ACCEPTED = 202,
585         NNG_HTTP_STATUS_NOT_AUTHORITATIVE = 203,
586         NNG_HTTP_STATUS_NO_CONTENT = 204,
587         NNG_HTTP_STATUS_RESET_CONTENT = 205,
588         NNG_HTTP_STATUS_PARTIAL_CONTENT = 206,
589         NNG_HTTP_STATUS_MULTI_STATUS = 207,
590         NNG_HTTP_STATUS_ALREADY_REPORTED = 208,
591         NNG_HTTP_STATUS_IM_USED = 226,
592         NNG_HTTP_STATUS_MULTIPLE_CHOICES = 300,
593         NNG_HTTP_STATUS_STATUS_MOVED_PERMANENTLY = 301,
594         NNG_HTTP_STATUS_FOUND = 302,
595         NNG_HTTP_STATUS_SEE_OTHER = 303,
596         NNG_HTTP_STATUS_NOT_MODIFIED = 304,
597         NNG_HTTP_STATUS_USE_PROXY = 305,
598         NNG_HTTP_STATUS_TEMPORARY_REDIRECT = 307,
599         NNG_HTTP_STATUS_PERMANENT_REDIRECT = 308,
600         NNG_HTTP_STATUS_BAD_REQUEST = 400,
601         NNG_HTTP_STATUS_UNAUTHORIZED = 401,
602         NNG_HTTP_STATUS_PAYMENT_REQUIRED = 402,
603         NNG_HTTP_STATUS_FORBIDDEN = 403,
604         NNG_HTTP_STATUS_NOT_FOUND = 404,
605         NNG_HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
606         NNG_HTTP_STATUS_NOT_ACCEPTABLE = 406,
607         NNG_HTTP_STATUS_PROXY_AUTH_REQUIRED = 407,
608         NNG_HTTP_STATUS_REQUEST_TIMEOUT = 408,
609         NNG_HTTP_STATUS_CONFLICT = 409,
610         NNG_HTTP_STATUS_GONE = 410,
611         NNG_HTTP_STATUS_LENGTH_REQUIRED = 411,
612         NNG_HTTP_STATUS_PRECONDITION_FAILED = 412,
613         NNG_HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
614         NNG_HTTP_STATUS_ENTITY_TOO_LONG = 414,
615         NNG_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
616         NNG_HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416,
617         NNG_HTTP_STATUS_EXPECTATION_FAILED = 417,
618         NNG_HTTP_STATUS_TEAPOT = 418,
619         NNG_HTTP_STATUS_UNPROCESSABLE_ENTITY = 422,
620         NNG_HTTP_STATUS_LOCKED = 423,
621         NNG_HTTP_STATUS_FAILED_DEPENDENCY = 424,
622         NNG_HTTP_STATUS_UPGRADE_REQUIRED = 426,
623         NNG_HTTP_STATUS_PRECONDITION_REQUIRED = 428,
624         NNG_HTTP_STATUS_TOO_MANY_REQUESTS = 429,
625         NNG_HTTP_STATUS_HEADERS_TOO_LARGE = 431,
626         NNG_HTTP_STATUS_UNAVAIL_LEGAL_REASONS = 451,
627         NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
628         NNG_HTTP_STATUS_NOT_IMPLEMENTED = 501,
629         NNG_HTTP_STATUS_BAD_GATEWAY = 502,
630         NNG_HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
631         NNG_HTTP_STATUS_GATEWAY_TIMEOUT = 504,
632         NNG_HTTP_STATUS_HTTP_VERSION_NOT_SUPP = 505,
633         NNG_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506,
634         NNG_HTTP_STATUS_INSUFFICIENT_STORAGE = 507,
635         NNG_HTTP_STATUS_LOOP_DETECTED = 508,
636         NNG_HTTP_STATUS_NOT_EXTENDED = 510,
637         NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED = 511,
638     };
639 
640     // http structures
641     struct nng_http_server {
642     };
643     struct nng_http_req {
644     };
645     struct nng_http_res {
646     };
647     struct nng_http_conn {
648     };
649     struct nng_http_handler {
650     };
651     struct nng_http_client {
652     };
653 
654     struct nng_url {
655         char* u_rawurl; // never NULL
656         char* u_scheme; // never NULL
657         char* u_userinfo; // will be NULL if not specified
658         char* u_host; // including colon and port
659         char* u_hostname; // name only, will be "" if not specified
660         char* u_port; // port, will be "" if not specified
661         char* u_path; // path, will be "" if not specified
662         char* u_query; // without '?', will be NULL if not specified
663         char* u_fragment; // without '#', will be NULL if not specified
664         char* u_requri; // includes query and fragment, "" if not specified
665     };
666 
667     // http url api
668     int nng_url_parse(nng_url**, const char*);
669     void nng_url_free(nng_url*);
670     int nng_url_clone(nng_url**, const nng_url*);
671 
672     // http request api
673     int nng_http_req_alloc(nng_http_req**, const nng_url*);
674     void nng_http_req_free(nng_http_req*);
675     char* nng_http_req_get_method(nng_http_req*);
676     char* nng_http_req_get_version(nng_http_req*);
677     char* nng_http_req_get_uri(nng_http_req*);
678     int nng_http_req_set_header(nng_http_req*, const char*, const char*);
679     int nng_http_req_add_header(nng_http_req*, const char*, const char*);
680     int nng_http_req_del_header(nng_http_req*, const char*);
681     char* nng_http_req_get_header(nng_http_req*, const char*);
682     int nng_http_req_set_method(nng_http_req*, const char*);
683     int nng_http_req_set_version(nng_http_req*, const char*);
684     int nng_http_req_set_uri(nng_http_req*, const char*);
685     int nng_http_req_set_data(nng_http_req*, const void*, size_t);
686     int nng_http_req_copy_data(nng_http_req*, const void*, size_t);
687     void nng_http_req_get_data(nng_http_req*, void**, size_t*);
688     void nng_http_req_reset(nng_http_req*);
689 
690     // http reply api
691     int nng_http_res_alloc(nng_http_res**);
692     int nng_http_res_alloc_error(nng_http_res**, ushort);
693     void nng_http_res_free(nng_http_res*);
694     ushort nng_http_res_get_status(nng_http_res*);
695     int nng_http_res_set_status(nng_http_res*, ushort);
696     char* nng_http_res_get_reason(nng_http_res*);
697     int nng_http_res_set_reason(nng_http_res*, const char*);
698     int nng_http_res_set_header(nng_http_res*, const char*, const char*);
699     int nng_http_res_add_header(nng_http_res*, const char*, const char*);
700     int nng_http_res_del_header(nng_http_res*, const char*);
701     char* nng_http_res_get_header(nng_http_res*, const char*);
702     int nng_http_res_set_version(nng_http_res*, const char*);
703     char* nng_http_res_get_version(nng_http_res*);
704     void nng_http_res_get_data(nng_http_res*, void**, size_t*);
705     int nng_http_res_set_data(nng_http_res*, const void*, size_t);
706     int nng_http_res_copy_data(nng_http_res*, const void*, size_t);
707     void nng_http_res_reset(nng_http_res*);
708 
709     // http connection api
710     void nng_http_conn_close(nng_http_conn*);
711     void nng_http_conn_read(nng_http_conn*, nng_aio*);
712     void nng_http_conn_read_all(nng_http_conn*, nng_aio*);
713     void nng_http_conn_write(nng_http_conn*, nng_aio*);
714     void nng_http_conn_write_all(nng_http_conn*, nng_aio*);
715     void nng_http_conn_write_req(nng_http_conn*, nng_http_req*, nng_aio*);
716     void nng_http_conn_write_res(nng_http_conn*, nng_http_res*, nng_aio*);
717     void nng_http_conn_read_req(nng_http_conn*, nng_http_req*, nng_aio*);
718     void nng_http_conn_read_res(nng_http_conn*, nng_http_res*, nng_aio*);
719     void nng_http_conn_transact(nng_http_conn*, nng_http_req*, nng_http_res*, nng_aio*);
720 
721     // http handler api
722     int nng_http_handler_alloc(nng_http_handler**, const char*, nng_http_cb);
723     int nng_http_handler_alloc_file(nng_http_handler**, const char*, const char*);
724     int nng_http_handler_alloc_static(nng_http_handler**, const char*, const void*, size_t, const char*);
725     int nng_http_handler_alloc_redirect(nng_http_handler**, const char*, ushort, const char*);
726     int nng_http_handler_alloc_directory(nng_http_handler**, const char*, const char*);
727     void nng_http_handler_free(nng_http_handler*);
728     int nng_http_handler_set_method(nng_http_handler*, const char*);
729     int nng_http_handler_set_host(nng_http_handler*, const char*);
730     int nng_http_handler_collect_body(nng_http_handler*, bool, size_t);
731     int nng_http_handler_set_tree(nng_http_handler*);
732     int nng_http_handler_set_tree_exclusive(nng_http_handler*);
733     int nng_http_handler_set_data(nng_http_handler*, void*, nng_cb);
734     void* nng_http_handler_get_data(nng_http_handler*);
735 
736     // http server api
737     int nng_http_server_hold(nng_http_server**, const nng_url*);
738     void nng_http_server_release(nng_http_server*);
739     int nng_http_server_start(nng_http_server*);
740     void nng_http_server_stop(nng_http_server*);
741     int nng_http_server_add_handler(nng_http_server*, nng_http_handler*);
742     int nng_http_server_del_handler(nng_http_server*, nng_http_handler*);
743     int nng_http_server_get_addr(nng_http_server*, nng_sockaddr*);
744     int nng_http_server_set_error_page(nng_http_server*, ushort, const char*);
745     int nng_http_server_set_error_file(nng_http_server*, ushort, const char*);
746     int nng_http_server_res_error(nng_http_server*, nng_http_res*);
747 
748     int nng_http_hijack(nng_http_conn*);
749 
750     // http client api
751     int nng_http_client_alloc(nng_http_client**, const nng_url*);
752     void nng_http_client_free(nng_http_client*);
753     void nng_http_client_connect(nng_http_client*, nng_aio*);
754     void nng_http_client_transact(nng_http_client*, nng_http_req*, nng_http_res*, nng_aio*);
755 
756     version (withtls) {
757 
758         enum nng_tls_mode {
759             NNG_TLS_MODE_CLIENT = 0,
760             NNG_TLS_MODE_SERVER = 1,
761         };
762         enum nng_tls_auth_mode {
763             NNG_TLS_AUTH_MODE_NONE = 0,
764             NNG_TLS_AUTH_MODE_OPTIONAL = 1,
765             NNG_TLS_AUTH_MODE_REQUIRED = 2,
766         };
767         enum nng_tls_version {
768             NNG_TLS_1_0 = 0x301,
769             NNG_TLS_1_1 = 0x302,
770             NNG_TLS_1_2 = 0x303,
771             NNG_TLS_1_3 = 0x304
772         };
773 
774         struct nng_tls_config {
775         };
776 
777         // http tls api
778         int nng_tls_config_alloc(nng_tls_config**, nng_tls_mode);
779         void nng_tls_config_hold(nng_tls_config*);
780         void nng_tls_config_free(nng_tls_config*);
781         int nng_tls_config_server_name(nng_tls_config*, const char*);
782         int nng_tls_config_ca_chain(nng_tls_config*, const char*, const char*);
783         int nng_tls_config_own_cert(nng_tls_config*, const char*, const char*, const char*);
784         int nng_tls_config_key(nng_tls_config*, const ubyte*, size_t);
785         int nng_tls_config_pass(nng_tls_config*, const char*);
786         int nng_tls_config_auth_mode(nng_tls_config*, nng_tls_auth_mode);
787         int nng_tls_config_ca_file(nng_tls_config*, const char*);
788         int nng_tls_config_cert_key_file(nng_tls_config*, const char*, const char*);
789         int nng_tls_config_version(nng_tls_config*, nng_tls_version, nng_tls_version);
790         char* nng_tls_engine_name();
791         char* nng_tls_engine_description();
792         bool nng_tls_engine_fips_mode();
793 
794         int nng_http_server_set_tls(nng_http_server*, nng_tls_config*);
795         int nng_http_server_get_tls(nng_http_server*, nng_tls_config**);
796         int nng_http_client_set_tls(nng_http_client*, nng_tls_config*);
797         int nng_http_client_get_tls(nng_http_client*, nng_tls_config**);
798 
799     }
800 
801 }