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