1 /**
2     http://nanomsg.org
3 
4     nanomsg is a socket library that provides several common communication patterns. It aims to make the networking layer fast, scalable, and easy to use.
5     Implemented in C, it works on a wide range of operating systems with no further dependencies.
6 
7     This module implements D bindings for nanomsg.
8 
9     Authors: Laeeth Isharc and Atila Neves (Kaleidic Associates Advisory Limited)
10     Date: April 20, 2017
11     Written: 2014,2015,2016,2017
12 
13     Caveat emptor.
14     Copyright:
15         https://github.com/nanomsg/nanomsg/blob/master/COPYING
16 
17  */
18 module nanomsg.bindings;
19 
20 
21 @nogc:
22 nothrow:
23 
24 // Note that comments beginning /** followed by a new line are highlighted in sublime, so please keep this formatting */
25 
26 extern(C) @system nothrow @nogc align(1):
27 
28 ///
29 enum PROTO_SP = 1;
30 ///
31 enum SP_HDR = 1;
32 ///
33 enum NN_H_INCLUDED = 1;
34 
35 /**
36     ABI versioning support:
37     The current interface version.
38 */
39 enum
40 {
41     /// 5
42     NN_VERSION_CURRENT = 5,
43     /// 0
44     NN_VERSION_REVISION = 0,
45     /// 0
46     NN_VERSION_AGE = 0,
47 }
48 
49 /**
50     Errors:
51         On some platforms some standard POSIX errnos are not defined
52 */
53 enum
54 {
55 
56     /// A number random enough not to collide with different errno ranges on
57     /// different OSes. The assumption is that error_t is at least 32-bit type.
58     NN_HAUSNUMERO=156384712,
59 ///
60     ENOTSUP=(NN_HAUSNUMERO + 1),
61 ///
62     EPROTONOSUPPORT =(NN_HAUSNUMERO + 2),
63 ///
64     ENOBUFS =(NN_HAUSNUMERO + 3),
65 ///
66     ENETDOWN =(NN_HAUSNUMERO + 4),
67 ///
68     EADDRINUSE =(NN_HAUSNUMERO + 5),
69 ///
70     EADDRNOTAVAIL =(NN_HAUSNUMERO + 6),
71 ///
72     ECONNREFUSED =(NN_HAUSNUMERO + 7),
73 ///
74     EINPROGRESS =(NN_HAUSNUMERO + 8),
75 ///
76     ENOTSOCK =(NN_HAUSNUMERO + 9),
77 ///
78     EAFNOSUPPORT =(NN_HAUSNUMERO + 10),
79 ///
80     EPROTO =(NN_HAUSNUMERO + 11),
81 ///
82     EAGAIN =(NN_HAUSNUMERO + 12),
83 ///
84     EBADF =(NN_HAUSNUMERO + 13),
85 ///
86     EINVAL= (NN_HAUSNUMERO + 14),
87 ///
88     EMFILE =(NN_HAUSNUMERO + 15),
89 ///
90     EFAULT =(NN_HAUSNUMERO + 16),
91 ///
92     EACCESS =(NN_HAUSNUMERO + 17),
93 ///
94     ENETRESET =(NN_HAUSNUMERO + 18),
95 ///
96     ENETUNREACH =(NN_HAUSNUMERO + 19),
97 ///
98     EHOSTUNREACH= (NN_HAUSNUMERO + 20),
99 ///
100     ENOTCONN =(NN_HAUSNUMERO + 21),
101 ///
102     EMSGSIZE= (NN_HAUSNUMERO + 22),
103 ///
104     ETIMEDOUT= (NN_HAUSNUMERO + 23),
105 ///
106     ECONNABORTED= (NN_HAUSNUMERO + 24),
107 ///
108     ECONNRESET =(NN_HAUSNUMERO + 25),
109 ///
110     ENOPROTOOPT =(NN_HAUSNUMERO + 26),
111 ///
112     EISCONN =(NN_HAUSNUMERO + 27),
113 ///
114     NN_EISCONN_DEFINED=1,
115 ///
116     ESOCKTNOSUPPORT =(NN_HAUSNUMERO + 28),
117 ///
118     ETERM =(NN_HAUSNUMERO + 53),
119 ///
120     EFSM =(NN_HAUSNUMERO + 54),
121 }
122 
123 /**
124     This function retrieves the errno as it is known to the library.
125      The goal of this function is to make the code 100% portable, including
126     where the library is compiled with certain CRT library (on Windows) and
127     linked to an application that uses different CRT library.
128 
129     Returns:
130         the errno as it is known to the library
131 */
132 extern (C) int nn_errno();
133 
134 /**
135     Resolves system errors and native errors to human-readable string.
136     Returns:
137         const(char)* human-readable string
138 */
139 extern (C) const(char)* nn_strerror (int errnum);
140 
141 
142 /**
143     Symbols:
144     Returns the symbol name (e.g. "NN_REQ") and value at a specified index.
145     If the index is out-of-range, returns 0 and sets errno to EINVAL
146     General usage is to start at i=0 and iterate until 0 is returned.
147 
148     Params:
149             i = index
150             v = pointer to value
151 
152     Returns:
153         symbol name eg "NN_REQ" and value at a specified index
154 */
155 extern (C) char *nn_symbol (int i, int *value);
156 
157 /**
158     Constants that are returned in `ns` member of nn_symbol_properties:
159 */
160 enum NN_NS
161 {
162     ///
163     NAMESPACE =0,
164     ///
165     VERSION =1,
166     ///
167     DOMAIN =2,
168     ///
169     TRANSPORT= 3,
170     ///
171     PROTOCOL =4,
172     ///
173     OPTION_LEVEL= 5,
174     ///
175     SOCKET_OPTION= 6,
176     ///
177     TRANSPORT_OPTION =7,
178     ///
179     OPTION_TYPE =8,
180     ///
181     OPTION_UNIT =9,
182     ///
183     FLAG =10,
184     ///
185     ERROR =11,
186     ///
187     LIMIT=12,
188     ///
189     EVENT=13,
190 }
191 ///
192 enum NN_NS_NAMESPACE = NN_NS.NAMESPACE;
193 ///
194 enum NN_NS_VERSION = NN_NS.VERSION;
195 ///
196 enum NN_NS_DOMAIN = NN_NS.DOMAIN;
197 ///
198 enum NN_NS_TRANSPORT = NN_NS.TRANSPORT;
199 ///
200 enum NN_NS_PROTOCOL = NN_NS.PROTOCOL;
201 ///
202 enum NN_NS_OPTION_LEVEL = NN_NS.OPTION_LEVEL;
203 ///
204 enum NN_NS_SOCKET_OPTION = NN_NS.SOCKET_OPTION;
205 ///
206 enum NN_NS_TRANSPORT_OPTION = NN_NS.TRANSPORT_OPTION;
207 ///
208 enum NN_NS_OPTION_TYPE = NN_NS.OPTION_TYPE;
209 ///
210 enum NN_NS_OPTION_UNIT = NN_NS.OPTION_UNIT;
211 ///
212 enum NN_NS_FLAG = NN_NS.FLAG;
213 ///
214 enum NN_NS_ERROR = NN_NS.ERROR;
215 ///
216 enum NN_NS_LIMIT = NN_NS.LIMIT;
217 ///
218 enum NN_NS_EVENT = NN_NS.EVENT;
219 
220 
221 /**
222     Constants that are returned in `ns` member of nn_symbol_properties
223 */
224 enum NN_TYPE
225 {
226     ///
227     NONE=0,
228     ///
229     INT=1,
230     ///
231     STR=2,
232 }
233 
234 ///
235 enum NN_TYPE_NONE = NN_TYPE.NONE;
236 ///
237 enum NN_TYPE_INT = NN_TYPE.INT;
238 ///
239 enum NN_TYPE_STR = NN_TYPE.STR;
240 
241 /**
242     Constants that are returned in `ns` member of nn_symbol_properties
243 */
244 enum NN_UNIT
245 {
246     ///
247     NONE =0,
248     ///
249     BYTES =1,
250     ///
251     MILLISECONDS =2,
252     ///
253     PRIORITY =3,
254     ///
255     BOOLEAN =4,
256 }
257 ///
258 enum NN_UNIT_NONE = NN_UNIT.NONE;
259 ///
260 enum NN_UNIT_BYTES = NN_UNIT.BYTES;
261 ///
262 enum NN_UNIT_MILLISECONDS = NN_UNIT.MILLISECONDS;
263 ///
264 enum NN_UNIT_PRIORITY = NN_UNIT.PRIORITY;
265 ///
266 enum NN_UNIT_BOOLEAN = NN_UNIT.BOOLEAN;
267 
268 /**
269     Structure that is returned from nn_symbol
270 */
271 align(1) struct nn_symbol_properties
272 {
273     ///  The constant value
274     int value;
275     ///  The constant name
276     const(char)* name;
277     /// The constant namespace, or zero for namespaces themselves
278     int ns;
279     /// The option type for socket option constants
280     int type;
281     /// The unit for the option value for socket option constants
282     int unit;
283 }
284 
285 /**
286     Fills in nn_symbol_properties structure and returns it's length
287     If the index is out-of-range, returns 0
288     General usage is to start at i=0 and iterate until zero is returned.
289 */
290 extern (C) int nn_symbol_info (int i, nn_symbol_properties* buf, int buflen);
291 
292 /// Termination:
293 /**
294     Helper function for shutting down multi-threaded applications
295 */
296 extern (C) void nn_term ();
297 
298 
299 /**
300     Zero-copy support:
301 */
302 
303 ///
304 enum NN_MSG= cast(size_t)-1;
305 ///
306 extern (C) void *nn_allocmsg (size_t size, int type);
307 ///
308 extern (C) void *nn_reallocmsg (void* msg, size_t size);
309 ///
310 extern (C) int nn_freemsg (void* msg);
311 
312 /**
313     Socket definition:
314 */
315 align(1) struct nn_iovec
316 {
317     void* iov_base;
318     size_t iov_len;
319 }
320 
321 /**
322     Message Header:
323 */
324 ///
325 align(1) struct nn_msghdr
326 {
327     nn_iovec* msg_iov;
328     int msg_iovlen;
329     void* msg_control;
330     size_t msg_controllen;
331 }
332 
333 ///
334 align(1) struct nn_cmsghdr
335 {
336     size_t cmsg_len;
337     int cmsg_level;
338     int cmsg_type;
339 }
340 
341 /*
342     Internal function. Not to be used directly.
343     Use NN_CMSG_NEXTHDR macro instead.
344 */
345 extern (C)  nn_cmsghdr* nn_cmsg_nexthdr_ (const(nn_msghdr)* mhdr,const(nn_cmsghdr)* cmsg);
346 
347 /**
348   rewritten from lambda syntax because libdparse does not recognise alias to a lambda
349   and docs won't be built because adrdox depends on it
350 */
351 pragma(inline)
352 auto NN_CMSG_ALIGN_ (long len)
353 {
354     return (len + size_t.sizeof - 1) & cast(size_t) ~(size_t.sizeof - 1);
355 }
356 
357 /// posix-defined msghdr manipulation
358 pragma(inline)
359 auto NN_CMSG_FIRSTHDR(T)(T* mhdr)
360 {
361     return nn_cmsg_nxthdr_ (cast(nn_msghdr*) mhdr, null);
362 }
363 
364 /// posix-defined msghdr manipulation
365 pragma(inline)
366 auto NN_CMSG_NXTHDR(T,U)(T* mhdr, U*cmsg)
367 {
368     return nn_cmsg_nxthdr_ (cast(nn_msghdr*) mhdr, cast(nn_cmsghdr*) cmsg);
369 }
370 
371 /// posix-defined msghdr manipulation
372 pragma(inline)
373 ubyte* NN_CMSG_DATA(T)(T* cmsg)
374 {
375     return cast(ubyte*) ((cast(nn_cmsghdr*) cmsg) + 1);
376 }
377 
378 /// Extension to POSIX defined by RFC 3542.
379 pragma(inline)
380 auto NN_CMSG_SPACE(size_t len)
381 {
382     return (NN_CMSG_ALIGN_ (len) + NN_CMSG_ALIGN_ (nn_cmsghdr.sizeof));
383 }
384 
385 /// Extension to POSIX defined by RFC 3542.
386 pragma(inline)
387 auto NN_CMSG_LEN(size_t len)
388 {
389     return (NN_CMSG_ALIGN_ (nn_cmsghdr.sizeof) + (len));
390 }
391 
392 /**
393     SP address families:
394 */
395 ///
396 enum AF_SP = 1;
397 ///
398 enum AF_SP_RAW = 2;
399 
400 /// Max size of an SP address
401 enum NN_SOCKADDR_MAX =128;
402 
403 /**
404     Socket options
405 */
406 
407 /// Socket option levels - Negative numbers are reserved for transports, positive for socket types.
408 enum NN_SOL_SOCKET =0;
409 
410 /// Generic socket options (NN_SOL_SOCKET level).
411 enum NN
412 {
413     ///
414     LINGER=1,
415     ///
416     SNDBUF =2,
417     ///
418     RCVBUF =3,
419     ///
420     SNDTIMEO =4,
421     ///
422     RCVTIMEO =5,
423     ///
424     RECONNECT_IVL= 6,
425     ///
426     RECONNECT_IVL_MAX =7,
427     ///
428     SNDPRIO =8,
429     ///
430     RCVPRIO= 9,
431     ///
432     SNDFD=10,
433     ///
434     RCVFD =11,
435     ///
436     DOMAIN =12,
437     ///
438     PROTOCOL =13,
439     ///
440     IPV4ONLY =14,
441     ///
442     SOCKET_NAME=15,
443     ///
444     RCVMAXSIZE=16,
445     ///
446     TTL=17,
447 }
448 // hints for docs
449 /// = NN.LINGER
450 enum NN_LINGER = NN.LINGER;
451 /// = NN.SNDBUF
452 enum NN_SNDBUF = NN.SNDBUF;
453 /// = NN.RCVBUF
454 enum NN_RCVBUF = NN.RCVBUF;
455 /// = NN.SNDTIME0
456 enum NN_SNDTIMEO = NN.SNDTIMEO;
457 /// = NN.RCVTIME0
458 enum NN_RCVTIMEO = NN.RCVTIMEO;
459 /// = NN.RECONNECT_IVL
460 enum NN_RECONNECT_IVL = NN.RECONNECT_IVL;
461 /// = NN.RECONNECT_IVL_MAX
462 enum NN_RECONNECT_IVL_MAX = NN.RECONNECT_IVL_MAX;
463 /// = NN.SNDPRIO
464 enum NN_SNDPRIO = NN.SNDPRIO;
465 /// = NN.RCVPRIO
466 enum NN_RCVPRIO = NN.RCVPRIO;
467 /// = NN.SNDFD
468 enum NN_SNDFD = NN.SNDFD;
469 /// = NN.RCVFD
470 enum NN_RCVFD = NN.RCVFD;
471 /// = NN.DOMAIN
472 enum NN_DOMAIN = NN.DOMAIN;
473 /// = NN.PROTOCOL
474 enum NN_PROTOCOL = NN.PROTOCOL;
475 /// = NN.IPV4ONLY
476 enum NN_IPV4ONLY = NN.IPV4ONLY;
477 /// = NN.SOCKET_NAME
478 enum NN_SOCKET_NAME = NN.SOCKET_NAME;
479 /// = NN.RCVMAXSIZE
480 enum NN_RCVMAXSIZE = NN.RCVMAXSIZE;
481 /// = NN.TTL
482 enum NN_TTL = NN.TTL;
483 
484 ///  Send/recv options.
485 enum NN_DONTWAIT =1;
486 
487 
488 ///
489 extern (C) int nn_socket(int domain, int protocol);
490 ///
491 extern (C) int nn_close(int s);
492 ///
493 extern (C) int nn_setsockopt(int s, int level, int option, const(void)* optval,size_t optvallen);
494 ///
495 extern (C) int nn_getsockopt(int s, int level, int option, void* optval,size_t* optvallen);
496 ///
497 extern (C) int nn_bind(int s, const(char)* addr);
498 ///
499 extern (C) int nn_connect(int s, const(char)* addr);
500 ///
501 extern (C) int nn_shutdown(int s, int how);
502 ///
503 extern (C) int nn_send(int s, const(void)* buf, size_t len, int flags);
504 ///
505 extern (C) int nn_recv(int s, void* buf, size_t len, int flags);
506 ///
507 extern (C) int nn_sendmsg(int s, nn_msghdr* msghdr, int flags);
508 ///
509 extern (C) int nn_sendmsg(int s, const(nn_msghdr)* msghdr, int flags);
510 ///
511 extern (C) int nn_recvmsg(int s,  nn_msghdr* msghdr, int flags);
512 
513 
514 /**
515     Socket multiplexing support:
516 */
517 
518 ///
519 enum NN_POLLIN  = 1;
520 ///
521 enum NN_POLLOUT = 2;
522 
523 ///
524 align(1) struct nn_pollfd
525 {
526     ///
527     int fd;
528     ///
529     short events;
530     ///
531     short revents;
532 }
533 
534 ///
535 extern(C) int nn_poll(nn_pollfd* fds, int nfds, int timeout);
536 
537 /**
538     Built-in support for devices.
539 */
540 extern(C) int nn_device(int s1, int s2);
541 
542 /**
543     Built-in support for multiplexers.
544 */
545 
546 extern(C) int nn_tcpmuxd (int port);
547 
548 
549 /**
550     PAIR:
551 */
552 ///
553 enum PAIR_H_INCLUDED=1;
554 ///
555 enum NN_PROTO_PAIR=1;
556 ///
557 enum NN_PAIR=(NN_PROTO_PAIR * 16 + 0);
558 ///
559 enum PIPELINE_H_INCLUDED=1;
560 
561 /**
562     PIPELINE:
563 */
564 ///
565 enum NN_PROTO_PIPELINE=5;
566 ///
567 enum NN_PUSH=(NN_PROTO_PIPELINE * 16 + 0);
568 ///
569 enum NN_PULL=(NN_PROTO_PIPELINE * 16 + 1);
570 
571 
572 
573 ///
574 enum NN_PROTOCOL_INCLUDED=1;
575 ///
576 struct nn_ctx;
577 ///
578 enum NN_PIPE
579 {
580     ///
581     RELEASE=1,
582     ///
583     PARSED=2,
584     ///
585     IN=33987,
586     ///
587     OUT=33988,
588 }
589 ///
590 struct nn_pipe;
591 ///
592 struct nn_msg;
593 
594 ///
595 extern(C)
596 {
597 ///
598     void nn_pipe_setdata ( nn_pipe *self, void *data);
599 ///
600     void *nn_pipe_getdata (nn_pipe *self);
601 ///
602     int nn_pipe_send(nn_pipe *self,  nn_msg *msg);
603 ///
604     int nn_pipe_recv ( nn_pipe *self, nn_msg *msg);
605 ///
606     void nn_pipe_getopt ( nn_pipe *self, int level, int option,void *optval, size_t *optvallen);
607 }
608 
609 
610 /**
611     Base class for all socket types:
612 
613     Any combination of these events can be returned from 'events' virtual
614     function.
615 */
616 ///
617 enum NN_SOCKBASE_EVENT_IN=1;
618 ///
619 enum NN_SOCKBASE_EVENT_OUT=2;
620 
621 /// To be implemented by individual socket types.
622 align(1) struct nn_sockbase_vfptr
623 {
624     extern(C) void function(nn_sockbase*) stop;
625     extern(C) void function(nn_sockbase*) destroy;
626     extern(C) int function(nn_sockbase*,nn_pipe*) add;
627     extern(C) void function(nn_sockbase*, nn_pipe*) rm;
628     extern(C) void function(nn_sockbase*, nn_pipe*) in_;
629     extern(C) void function(nn_sockbase*, nn_pipe*) out_;
630     extern(C) int function(nn_sockbase*) events;
631     extern(C) int function(nn_sockbase*, nn_msg*) send;
632     extern(C) int function(nn_sockbase*, nn_msg*) recv;
633     extern(C) int function(nn_sockbase*, int level, int option,const void* optval, size_t optvallen) setopt;
634     extern(C) int function(nn_sockbase*, int level, int option,void* optval, size_t *optvallen) getopt;
635 }
636 
637 ///
638 struct nn_sockbase
639 {
640     const(nn_sockbase_vfptr)* vfptr;
641      nn_sock *sock;
642 }
643 
644 /**
645     Initialise the socket base class. 'hint' is the opaque value passed to the
646     nn_transport's 'create' function.
647 */
648 extern(C) void nn_sockbase_init ( nn_sockbase *self,const  nn_sockbase_vfptr *vfptr, void *hint);
649 
650 /**
651 Terminate the socket base class.
652 */
653 extern(C) void nn_sockbase_term ( nn_sockbase *self);
654 
655 /**
656     Call this function when stopping is done.
657 */
658 extern(C) void nn_sockbase_stopped ( nn_sockbase *self);
659 
660 /**
661     Returns the AIO context associated with the socket. This function is
662     useful when socket type implementation needs to create async objects,
663     such as timers.
664 */
665 extern(C) nn_ctx *nn_sockbase_getctx ( nn_sockbase *self);
666 
667 /**
668     Retrieve a NN_SOL_SOCKET-level option.
669 */
670 extern(C) int nn_sockbase_getopt (nn_sockbase* self, int option, void* optval, size_t *optvallen);
671 
672 /**
673     Add some statistics for socket
674 */
675 extern(C) void nn_sockbase_stat_increment (nn_sockbase* self, int name,int increment);
676 
677 ///
678 enum NN_STAT_CURRENT_SND_PRIORITY=401;
679 
680 /// Specifies that the socket type can never be used to receive messages
681 enum NN_SOCKTYPE_FLAG_NORECV=1;
682 
683 /// Specifies that the socket type can never be used to send messages
684 enum NN_SOCKTYPE_FLAG_NOSEND=2;
685 
686 /**
687     The socktype class:
688         This structure defines a class factory for individual socket types.
689 */
690 struct nn_socktype {
691     int domain;
692     int protocol;
693     int flags;
694     int function(void *hint, nn_sockbase **sockbase) create;
695     int function(int socktype) ispeer;
696     nn_list_item* item;
697 }
698 
699 
700 /**
701     PUBSUB:
702 */
703 ///
704 enum NN_PROTO_PUBSUB=2;
705 ///
706 enum NN_PUB=NN_PROTO_PUBSUB * 16 + 0;
707 ///
708 enum NN_SUB=NN_PROTO_PUBSUB * 16 + 1;
709 ///
710 enum NN_SUB_SUBSCRIBE =1;
711 ///
712 enum NN_SUB_UNSUBSCRIBE=2;
713 
714 
715 /**
716     BUS:
717 */
718     enum NN_PROTO_BUS=7;
719     ///
720     enum NN_BUS = (NN_PROTO_BUS * 16 + 0);
721 
722 /**
723     INPROC:
724 */
725 enum NN_INPROC=-1;
726 
727 /**
728     IPC:
729 */
730 enum NN_IPC=-2;
731 
732 
733 /**
734     REQREP:
735 */
736 enum REQREP_H_INCLUDED=1;
737 ///
738 enum NN_PROTO_REQREP = 3;
739 ///
740 enum NN_REQ=NN_PROTO_REQREP * 16 + 0;
741 ///
742 enum NN_REP=NN_PROTO_REQREP * 16 + 1;
743 ///
744 enum NN_REQ_RESEND_IVL=1;
745 
746 ///
747 align(1) union nn_req_handle
748 {
749     int i;
750     void *ptr;
751 }
752 
753 ///
754 extern(C) int nn_req_send (int s, nn_req_handle hndl, const(void)* buf, size_t len, int flags);
755 ///
756 extern(C) int nn_req_recv (int s, nn_req_handle *hndl, void *buf, size_t len, int flags);
757 
758 
759 /**
760     TCPMUX:
761 */
762 enum NN_TCPMUX = -5;
763 ///
764 enum NN_TCPMUX_NODELAY = 1;
765 
766 /**
767     WS:
768 */
769 enum NN_WS = -4;
770 
771 /// websocket NN_WS level socket/cmsg option
772 /// Note that only NN_WSMG_TYPE_TEXT and NN_WS_MSG_TYPE_BINARY messages are supported fully by this
773 /// implementation.  Attempting to set other message types is undefined.
774 enum NN_WS_MSG_TYPE = 1;
775 
776 /// websockets opcode constant as per RFC 6455 5.2 - text
777 enum NN_WS_MSG_TYPE_TEXT = 0x01;
778 /// websockets opcode constant as per RFC 6455 5.2 - binary
779 enum NN_WS_MSG_TYPE_BINARY = 0x02;
780 
781 /**
782     SURVEY:
783 */
784 ///
785 enum SURVEY_H_INCLUDED=1;
786 ///
787 enum NN_PROTO_SURVEY=6;
788 ///
789 enum NN_SURVEYOR=(NN_PROTO_SURVEY * 16 + 2);
790 ///
791 enum NN_RESPONDENT=(NN_PROTO_SURVEY * 16 + 3);
792 ///
793 enum NN_SURVEYOR_DEADLINE=1;
794 
795 /**
796 */
797 ///
798 enum TCP_H_INCLUDED=1;
799 ///
800 enum NN_TCP=-3;
801 ///
802 enum NN_TCP_NODELAY=1;
803 ///
804 struct nn_sock;
805 ///
806 struct nn_cp;
807 ///
808 struct nn_ep;
809 
810 ///
811 struct nn_optset_vfptr
812 {
813     extern (C) void function(nn_optset *self) destroy;
814     extern (C) int function(nn_optset *self, int option, const(void)* optval,size_t optvallen) setopt;
815     extern (C) int function(nn_optset *self, int option, void *optval,size_t *optvallen) getopt;
816 }
817 
818 ///
819 struct nn_optset
820 {
821     const(nn_optset_vfptr)* vfptr;
822 }
823 
824 ///
825 struct nn_epbase_vfptr
826 {
827     extern (C) void function(nn_epbase *) stop;
828     extern (C) void function(nn_epbase *) destroy;
829 }
830 
831 ///
832 struct nn_epbase
833 {
834     const(nn_epbase_vfptr)* vfptr;
835      nn_ep *ep;
836 }
837 
838 /**
839     Endpoint:
840 */
841 
842 /**
843     Creates a new endpoint.
844     Parameters:
845         hint =  opaque value that was passed to transport's bind or connect function.
846 */
847 extern(C) void nn_epbase_init ( nn_epbase *self,const  nn_epbase_vfptr *vfptr, void *hint);
848 ///
849 extern(C) void nn_epbase_stopped ( nn_epbase *self);
850 ///
851 extern(C) void nn_epbase_term (nn_epbase *self);
852 ///
853 extern(C) nn_ctx *nn_epbase_getctx ( nn_epbase *self);
854 ///
855 extern(C) char *nn_epbase_getaddr ( nn_epbase *self);
856 ///
857 extern(C) void nn_epbase_getopt ( nn_epbase *self, int level, int option,void *optval, size_t *optvallen);
858 ///
859 extern(C) int nn_epbase_ispeer ( nn_epbase *self, int socktype);
860 ///
861 extern(C) void nn_epbase_set_error( nn_epbase *self, int errnum);
862 ///
863 extern(C) void nn_epbase_clear_error( nn_epbase *self);
864 ///
865 extern(C) void nn_epbase_stat_increment(nn_epbase *self, int name, int increment);
866 
867 
868 ///
869 enum NN_STAT
870 {
871     ESTABLISHED_CONNECTIONS=101,
872     ACCEPTED_CONNECTIONS    =102,
873     DROPPED_CONNECTIONS     =103,
874     BROKEN_CONNECTIONS      =104,
875     CONNECT_ERRORS          =105,
876     BIND_ERRORS             =106,
877     ACCEPT_ERRORS           =107,
878     CURRENT_CONNECTIONS     =201,
879     INPROGRESS_CONNECTIONS  =202,
880     CURRENT_EP_ERRORS       =203,
881 }
882 
883 ///
884 enum NN_PIPE_RELEASE=1;
885 ///
886 enum NN_PIPE_PARSED=2;
887 ///
888 enum NN_PIPE_IN=33987;
889 ///
890 enum NN_PIPE_OUT=33988;
891 
892 /// Pipebase:
893 ///
894 enum NN_PIPEBASE
895 {
896     RELEASE=1,
897     PARSED=2,
898 }
899 
900 ///
901 align(1) struct nn_pipebase_vfptr
902 {
903     alias _send=extern(C) int function(nn_pipebase* self, nn_msg* msg);
904     alias _recv=extern(C) int function(nn_pipebase* self,  nn_msg* msg);
905     _send send;
906     _recv recv;
907 }
908 
909 
910 ///
911 align(1) struct nn_ep_options
912 {
913     int sndprio;
914     int rcvprio;
915     int ipv4only;
916 }
917 
918 ///
919 align(1) struct nn_pipebase
920 {
921     nn_fsm fsm;
922     const nn_pipebase_vfptr* vfptr;
923     ubyte state;
924     ubyte instate;
925     ubyte outstate;
926     nn_sock *sock;
927     void *data;
928     nn_fsm_event IN;
929     nn_fsm_event OUT;
930     nn_ep_options options;
931 }
932 
933 ///
934 extern(C) void nn_pipebase_init (nn_pipebase*,const(nn_pipebase_vfptr)* vfptr, nn_epbase* epbase);
935 ///
936 extern(C) void nn_pipebase_term ( nn_pipebase*);
937 ///
938 extern(C) int nn_pipebase_start ( nn_pipebase*);
939 ///
940 extern(C) void nn_pipebase_stop ( nn_pipebase*);
941 ///
942 extern(C) void nn_pipebase_received ( nn_pipebase*);
943 ///
944 extern(C) void nn_pipebase_sent ( nn_pipebase*);
945 ///
946 extern(C) void nn_pipebase_getopt ( nn_pipebase* , int level, int option,void *optval, size_t *optvallen);
947 ///
948 extern(C) int nn_pipebase_ispeer ( nn_pipebase*, int socktype);
949 ///
950 extern(C) void nn_pipe_setdata(nn_pipe *self, void *data);
951 ///
952 extern(C) void *nn_pipe_getdata ( nn_pipe *self);
953 ///
954 extern(C) int nn_pipe_send ( nn_pipe *self, nn_msg *msg);
955 ///
956 extern(C) int nn_pipe_recv ( nn_pipe *self, nn_msg *msg);
957 ///
958 extern(C) void nn_pipe_getopt (nn_pipe *self, int level, int option, void *optval, size_t *optvallen);
959 
960 /**
961     Transport:
962 */
963 ///
964 align(1) struct nn_transport
965 {
966     const(char*) name;
967     int id;
968     extern(C) void function() init;
969     extern(C) void function() term;
970     extern(C) int function(void *hint, nn_epbase **epbase) bind;
971     extern(C) int function(void *hint,  nn_epbase **epbase) connect;
972     extern(C) nn_optset* function() optset;
973     nn_list_item item;
974 }
975 
976 /**
977     FSM:
978 */
979 enum NN_FSM_INCLUDED=1;
980 
981 ///
982 align(1) struct nn_worker;
983 ///
984 align(1) struct nn_fsm_event
985 {
986     nn_fsm* fsm;
987     int src;
988     void* srcptr;
989     int type;
990     nn_queue_item item;
991 }
992 
993 
994 ///
995 extern(C) void nn_fsm_event_init(nn_fsm_event *self);
996 ///
997 extern(C) void nn_fsm_event_term(nn_fsm_event *self);
998 ///
999 extern(C) int nn_fsm_event_active(nn_fsm_event *self);
1000 ///
1001 extern(C) void nn_fsm_event_process(nn_fsm_event *self);
1002 
1003 
1004 /**
1005     Special source for actions. It's negative not to clash with user-defined sources.
1006 */
1007 enum NN_FSM_ACTION =-2;
1008 
1009 /**
1010 Actions generated by fsm object. The values are negative not to clash with user-defined actions.
1011 */
1012 enum NN_FSM_START=-2;
1013 ///
1014 enum NN_FSM_STOP =-3;
1015 
1016 /**
1017     Virtual function to be implemented by the derived class to handle the incoming events.
1018 */
1019 alias nn_fsm_fn = extern(C) void function(nn_fsm*, int, int, void*);
1020 
1021 ///
1022 align(1) struct nn_fsm_owner
1023 {
1024     int src;
1025     nn_fsm *fsm;
1026 }
1027 
1028 ///
1029 align(1) struct nn_fsm
1030 {
1031     nn_fsm_fn fn;
1032     nn_fsm_fn shutdown_fn;
1033     int state;
1034     int src;
1035     void *srcptr;
1036     nn_fsm *owner;
1037     nn_ctx *ctx;
1038     nn_fsm_event stopped;
1039 }
1040 
1041 
1042 ///
1043 extern(C) void nn_fsm_init_root(nn_fsm *self, nn_fsm_fn fn,nn_fsm_fn shutdown_fn, nn_ctx* ctx);
1044 ///
1045 extern(C) void nn_fsm_init(nn_fsm *, nn_fsm_fn fn,nn_fsm_fn shutdown_fn,int src, void *srcptr, nn_fsm* owner);
1046 ///
1047 extern(C) void nn_fsm_term(nn_fsm *);
1048 ///
1049 extern(C) int nn_fsm_isidle(nn_fsm *);
1050 ///
1051 extern(C) void nn_fsm_start(nn_fsm *);
1052 ///
1053 extern(C) void nn_fsm_stop(nn_fsm *);
1054 ///
1055 extern(C) void nn_fsm_stopped(nn_fsm*, int type);
1056 ///
1057 extern(C) void nn_fsm_stopped_noevent(nn_fsm*);
1058 ///
1059 extern(C) void nn_fsm_swap_owner(nn_fsm*, nn_fsm_owner* owner);
1060 ///
1061 extern(C) nn_worker* nn_fsm_choose_worker(nn_fsm*);
1062 ///
1063 extern(C) void nn_fsm_action(nn_fsm*, int type);
1064 ///
1065 extern(C) void nn_fsm_raise(nn_fsm*, nn_fsm_event* event, int type);
1066 ///
1067 extern(C) void nn_fsm_raiseto(nn_fsm*, nn_fsm* dst, nn_fsm_event* event, int src, int type, void *srcptr);
1068 ///
1069 extern(C) void nn_fsm_feed(nn_fsm*, int src, int type, void* srcptr);
1070 
1071 
1072 ///
1073 enum NN_LIST_INCLUDED=1;
1074 
1075 ///
1076 align(1) struct nn_list_item
1077 {
1078     nn_list_item* next;
1079     nn_list_item* prev;
1080 }
1081 
1082 ///
1083 align(1) struct nn_list
1084 {
1085     nn_list_item* first;
1086     nn_list_item* last;
1087 }
1088 
1089 /// Undefined value for initializing a list item which is not part of a list.
1090 enum NN_LIST_NOTINLIST = cast(const(nn_list_item)*)-1;
1091 
1092 /// Use for initializing a list item statically.
1093 immutable typeof(NN_LIST_NOTINLIST)[2] NN_LIST_ITEM_INITIALIZER=[NN_LIST_NOTINLIST, NN_LIST_NOTINLIST];
1094 
1095 
1096 /// Initialise the list.
1097 extern(C) void nn_list_init(nn_list*);
1098 ///
1099 extern(C) void nn_list_term(nn_list*);
1100 ///
1101 extern(C) int nn_list_empty(nn_list*);
1102 ///
1103 extern(C) nn_list_item* nn_list_begin(nn_list*);
1104 ///
1105 extern(C) nn_list_item* nn_list_end(nn_list*);
1106 ///
1107 extern(C) nn_list_item *nn_list_prev(nn_list*,nn_list_item*);
1108 ///
1109 extern(C) nn_list_item *nn_list_next(nn_list*,nn_list_item*);
1110 ///
1111 extern(C) void nn_list_insert(nn_list*, nn_list_item*, nn_list_item*);
1112 ///
1113 extern(C) nn_list_item* nn_list_erase(nn_list*,nn_list_item*);
1114 ///
1115 extern(C) void nn_list_item_init(nn_list_item*);
1116 ///
1117 extern(C) void nn_list_item_term(nn_list_item*);
1118 ///
1119 extern(C) int nn_list_item_isinlist(nn_list_item*);
1120 
1121 
1122 /**
1123     Queues:
1124 */
1125 ///
1126 enum NN_QUEUE_INCLUDED = 1;
1127 
1128 /// Undefined value for initialising a queue item which is not part of a queue.
1129 const(nn_queue_item)* NN_QUEUE_NOTINQUEUE=cast(const(nn_queue_item)*) -1;
1130 
1131 
1132 /**
1133     Use for initialising a queue item statically.
1134 
1135     $(COMMENT
1136         auto NN_QUEUE_ITEM_INITIALIZER()
1137         {
1138             return [NN_LIST_NOTINQUEUE];
1139         }
1140     )
1141 */
1142 
1143 ///
1144 align(1) struct nn_queue_item
1145 {
1146     nn_queue_item *next;
1147 }
1148 
1149 ///
1150 align(1) struct nn_queue
1151 {
1152     nn_queue_item *head;
1153     nn_queue_item *tail;
1154 }
1155 
1156 ///
1157 extern(C) void nn_queue_init(nn_queue*);
1158 ///
1159 extern(C) void nn_queue_term(nn_queue*);
1160 ///
1161 extern(C) int nn_queue_empty(nn_queue*);
1162 ///
1163 extern(C) void nn_queue_push(nn_queue*, nn_queue_item*);
1164 ///
1165 extern(C) nn_queue_item *nn_queue_pop( nn_queue*);
1166 ///
1167 extern(C) void nn_queue_item_init(nn_queue_item*);
1168 ///
1169 extern(C) void nn_queue_item_term(nn_queue_item*);
1170 ///
1171 extern(C) int nn_queue_item_isinqueue(nn_queue_item*);
1172 
1173 
1174 
1175 /**
1176     Returns the symbol name (e.g. "NN_REQ") and value at a specified index.
1177     If the index is out-of-range, returns null and sets errno to EINVAL
1178     General usage is to start at i=0 and iterate until null is returned.
1179 */
1180 extern(C) const(char)* nn_symbol (int i, int *value);
1181 
1182 
1183 /// Associates opaque pointer to protocol-specific data with the pipe.
1184 extern(C) void nn_pipe_setdata (nn_pipe *self, void *data);
1185 
1186 /// Retrieves the opaque pointer associated with the pipe.
1187 extern(C) void *nn_pipe_getdata (nn_pipe* self);
1188 
1189 /// Send the message to the pipe. If successful, pipe takes ownership of the messages.
1190 extern(C) int nn_pipe_send (nn_pipe* self, nn_msg* msg);
1191 
1192 /// Receive a message from a pipe. 'msg' should not be initialised prior to the call.
1193 /// It will be initialised when the call succeeds.
1194 extern(C) int nn_pipe_recv (nn_pipe* self, nn_msg* msg);
1195 
1196 /// Get option for pipe. Mostly useful for endpoint-specific options
1197 extern(C) void nn_pipe_getopt (nn_pipe* self, int level, int option, void* optval, size_t* optvallen);
1198 
1199 
1200 /**
1201     Base class for all socket types:
1202 */
1203 
1204 /// Initialise the socket base class. 'hint' is the opaque value passed to the
1205 /// nn_transport's 'create' function.
1206 extern(C) void nn_sockbase_init (nn_sockbase* self, const(nn_sockbase_vfptr)* vfptr, void* hint);
1207 
1208 /// Terminate the socket base class.
1209 extern(C) void nn_sockbase_term (nn_sockbase* self);
1210 
1211 /// Call this function when stopping is done.
1212 extern(C) void nn_sockbase_stopped (nn_sockbase* self);
1213 
1214 /// Returns the AIO context associated with the socket. This function is
1215 /// useful when socket type implementation needs to create async objects,
1216 /// such as timers.
1217 extern(C) nn_ctx *nn_sockbase_getctx (nn_sockbase *self);
1218 
1219 /// Retrieve a NN_SOL_SOCKET-level option.
1220 extern(C) int nn_sockbase_getopt (nn_sockbase *self, int option, void *optval, size_t *optvallen);
1221 
1222 /// Add some statistics for socket
1223 extern(C) void nn_sockbase_stat_increment (nn_sockbase *self, int name, int increment);
1224 
1225 /// Creates a new endpoint. 'hint' parameter is an opaque value that
1226 /// was passed to transport's bind or connect function.
1227 extern(C) void nn_epbase_init (nn_epbase* self, const(nn_epbase_vfptr)* vfptr, void *hint);
1228 
1229 /// Notify the user that stopping is done.
1230 extern(C) void nn_epbase_stopped (nn_epbase* self);
1231 
1232 /// Terminate the epbase object.
1233 extern(C) void nn_epbase_term (nn_epbase* self);
1234 
1235 /// Returns the AIO context associated with the endpoint.
1236 extern(C) nn_ctx *nn_epbase_getctx (nn_epbase* self);
1237 
1238 /// Returns the address string associated with this endpoint.
1239 extern(C) const(char*) nn_epbase_getaddr (nn_epbase* self);
1240 
1241 /// Retrieve value of a socket option.
1242 extern(C) void nn_epbase_getopt (nn_epbase* self, int level, int option, void *optval, size_t *optvallen);
1243 
1244 /// Returns:
1245 ///     1 is the specified socket type is a valid peer for this socket,
1246 ///     or 0 otherwise.
1247 extern(C) int nn_epbase_ispeer (nn_epbase* self, int socktype);
1248 
1249 /// Notifies a monitoring system the error on this endpoint
1250 extern(C) void nn_epbase_set_error(nn_epbase* self, int errnum);
1251 
1252 /// Notifies a monitoring system that error is gone
1253 extern(C) void nn_epbase_clear_error(nn_epbase* self);
1254 
1255 /// Increments statistics counters in the socket structure
1256 extern(C) void nn_epbase_stat_increment(nn_epbase* self, int name, int increment);
1257 
1258 /// Statistics:
1259 ///
1260 enum NN_STAT_ESTABLISHED_CONNECTIONS =101;
1261 ///
1262 enum NN_STAT_ACCEPTED_CONNECTIONS    =102;
1263 ///
1264 enum NN_STAT_DROPPED_CONNECTIONS     =103;
1265 ///
1266 enum NN_STAT_BROKEN_CONNECTIONS      =104;
1267 ///
1268 enum NN_STAT_CONNECT_ERRORS          =105;
1269 ///
1270 enum NN_STAT_BIND_ERRORS             =106;
1271 ///
1272 enum NN_STAT_ACCEPT_ERRORS           =107;
1273 ///
1274 enum NN_STAT_CURRENT_CONNECTIONS     =201;
1275 ///
1276 enum NN_STAT_INPROGRESS_CONNECTIONS  =202;
1277 ///
1278 enum NN_STAT_CURRENT_EP_ERRORS       =203;
1279 
1280 
1281 /**
1282     The base class for pipes:
1283 
1284     Pipe represents one "connection", i.e. perfectly ordered uni- or
1285     bi-directional stream of messages. One endpoint can create multiple pipes
1286     (for example, bound TCP socket is an endpoint, individual accepted TCP
1287     connections are represented by pipes.
1288 
1289     This value is returned by pipe's send and recv functions to signalise that
1290     more sends/recvs are not possible at the moment. From that moment on,
1291     the core will stop invoking the function. To re-establish the message
1292     flow nn_pipebase_received (respectively nn_pipebase_sent) should
1293     be called.
1294 */
1295 enum NN_PIPEBASE_RELEASE = 1;
1296 
1297 /**
1298     Specifies that received message is already split into header and body.
1299     This flag is used only by inproc transport to avoid merging and re-splitting
1300     the messages passed with a single process.
1301 */
1302 enum NN_PIPEBASE_PARSED = 2;
1303 
1304 /// Initialise the pipe.
1305 extern(C) void nn_pipebase_init (nn_pipebase *self, const(nn_pipebase_vfptr)* vfptr, nn_epbase *epbase);
1306 
1307 /// Terminate the pipe.
1308 extern(C) void nn_pipebase_term (nn_pipebase *self);
1309 
1310 /// Call this function once the connection is established.
1311 extern(C) int nn_pipebase_start (nn_pipebase *self);
1312 
1313 /// Call this function once the connection is broken.
1314 extern(C) void nn_pipebase_stop (nn_pipebase *self);
1315 
1316 /// Call this function when new message was fully received.
1317 extern(C) void nn_pipebase_received (nn_pipebase *self);
1318 
1319 /// Call this function when current outgoing message was fully sent.
1320 extern(C) void nn_pipebase_sent (nn_pipebase *self);
1321 
1322 /// Retrieve value of a socket option.
1323 extern(C) void nn_pipebase_getopt (nn_pipebase *self, int level, int option, void *optval, size_t *optvallen);
1324 
1325 /// Returns 1 is the specified socket type is a valid peer for this socket, or 0 otherwise.
1326 extern(C) int nn_pipebase_ispeer (nn_pipebase *self, int socktype);