1 module nanomsg.bindings;
2 
3 
4 /**
5     Ported to Dlang (2014,2015,2016) by Laeeth Isharc.  Caveat emptor.
6 */
7 
8 extern(C) @system nothrow @nogc align(1):
9 
10 enum PROTO_SP = 1;
11 enum SP_HDR = 1;
12 enum NN_H_INCLUDED = 1;
13 
14 /******************************************************************************/
15 /*  ABI versioning support.                                                   */
16 /******************************************************************************/
17 
18 /*  Don't change this unless you know exactly what you're doing and have      */
19 /*  read and understand the following documents:                              */
20 /*  www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html     */
21 /*  www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html  */
22 
23 /*  The current interface version. */
24 enum
25 {
26     NN_VERSION_CURRENT = 5,
27     NN_VERSION_REVISION = 0,
28     NN_VERSION_AGE = 0,
29 }
30 
31 /******************************************************************************/
32 /*  Errors.                                                                   */
33 /******************************************************************************/
34 
35 /*  A number random enough not to collide with different errno ranges on      */
36 /*  different OSes. The assumption is that error_t is at least 32-bit type.   */
37 enum
38 {
39 
40     NN_HAUSNUMERO=156384712,
41 
42     /*  On some platforms some standard POSIX errnos are not defined.    */
43     ENOTSUP=(NN_HAUSNUMERO + 1),
44     EPROTONOSUPPORT =(NN_HAUSNUMERO + 2),
45     ENOBUFS =(NN_HAUSNUMERO + 3),
46     ENETDOWN =(NN_HAUSNUMERO + 4),
47     EADDRINUSE =(NN_HAUSNUMERO + 5),
48     EADDRNOTAVAIL =(NN_HAUSNUMERO + 6),
49     ECONNREFUSED =(NN_HAUSNUMERO + 7),
50     EINPROGRESS =(NN_HAUSNUMERO + 8),
51     ENOTSOCK =(NN_HAUSNUMERO + 9),
52     EAFNOSUPPORT =(NN_HAUSNUMERO + 10),
53     EPROTO =(NN_HAUSNUMERO + 11),
54     EAGAIN =(NN_HAUSNUMERO + 12),
55     EBADF =(NN_HAUSNUMERO + 13),
56     EINVAL= (NN_HAUSNUMERO + 14),
57     EMFILE =(NN_HAUSNUMERO + 15),
58     EFAULT =(NN_HAUSNUMERO + 16),
59     EACCESS =(NN_HAUSNUMERO + 17),
60     ENETRESET =(NN_HAUSNUMERO + 18),
61     ENETUNREACH =(NN_HAUSNUMERO + 19),
62     EHOSTUNREACH= (NN_HAUSNUMERO + 20),
63     ENOTCONN =(NN_HAUSNUMERO + 21),
64     EMSGSIZE= (NN_HAUSNUMERO + 22),
65     ETIMEDOUT= (NN_HAUSNUMERO + 23),
66     ECONNABORTED= (NN_HAUSNUMERO + 24),
67     ECONNRESET =(NN_HAUSNUMERO + 25),
68     ENOPROTOOPT =(NN_HAUSNUMERO + 26),
69     EISCONN =(NN_HAUSNUMERO + 27),
70     NN_EISCONN_DEFINED=1,
71     ESOCKTNOSUPPORT =(NN_HAUSNUMERO + 28),
72     ETERM =(NN_HAUSNUMERO + 53),
73     EFSM =(NN_HAUSNUMERO + 54),
74 }
75 
76 /**
77     This function retrieves the errno as it is known to the library.
78      The goal of this function is to make the code 100% portable, including
79     where the library is compiled with certain CRT library (on Windows) and
80     linked to an application that uses different CRT library.
81 
82     Returns: the errno as it is known to the library
83 */
84 extern (C) int nn_errno();
85 
86 /**  Resolves system errors and native errors to human-readable string.
87     Returns: const(char)* human-readable string
88 */
89 extern (C) const(char)* nn_strerror (int errnum);
90 
91 
92 /**
93     Returns the symbol name (e.g. "NN_REQ") and value at a specified index.
94     If the index is out-of-range, returns 0 and sets errno to EINVAL
95     General usage is to start at i=0 and iterate until 0 is returned.
96 
97     Params:
98             i = index
99             v = pointer to value
100 
101     Returns: symbol name eg "NN_REQ" and value at a specified index
102 */
103 extern (C) char *nn_symbol (int i, int *value);
104 
105 /*  Constants that are returned in `ns` member of nn_symbol_properties        */
106 enum NN_NS
107 {
108     NAMESPACE =0,
109     VERSION =1,
110     DOMAIN =2,
111     TRANSPORT= 3,
112     PROTOCOL =4,
113     OPTION_LEVEL= 5,
114     SOCKET_OPTION= 6,
115     TRANSPORT_OPTION =7,
116     OPTION_TYPE =8,
117     OPTION_UNIT =9,
118     FLAG =10,
119     ERROR =11,
120     LIMIT=12,
121     EVENT=13,
122 }
123 enum NN_NS_NAMESPACE = NN_NS.NAMESPACE;
124 enum NN_NS_VERSION = NN_NS.VERSION;
125 enum NN_NS_DOMAIN = NN_NS.DOMAIN;
126 enum NN_NS_TRANSPORT = NN_NS.TRANSPORT;
127 enum NN_NS_PROTOCOL = NN_NS.PROTOCOL;
128 enum NN_NS_OPTION_LEVEL = NN_NS.OPTION_LEVEL;
129 enum NN_NS_SOCKET_OPTION = NN_NS.SOCKET_OPTION;
130 enum NN_NS_TRANSPORT_OPTION = NN_NS.TRANSPORT_OPTION;
131 enum NN_NS_OPTION_TYPE = NN_NS.OPTION_TYPE;
132 enum NN_NS_OPTION_UNIT = NN_NS.OPTION_UNIT;
133 enum NN_NS_FLAG = NN_NS.FLAG;
134 enum NN_NS_ERROR = NN_NS.ERROR;
135 enum NN_NS_LIMIT = NN_NS.LIMIT;
136 enum NN_NS_EVENT = NN_NS.EVENT;
137 
138 
139 /**  Constants that are returned in `ns` member of nn_symbol_properties        */
140 enum NN_TYPE
141 {
142     NONE=0,
143     INT=1,
144     STR=2,
145 }
146 
147 enum NN_TYPE_NONE = NN_TYPE.NONE;
148 enum NN_TYPE_INT = NN_TYPE.INT;
149 enum NN_TYPE_STR = NN_TYPE.STR;
150 
151 /**  Constants that are returned in `ns` member of nn_symbol_properties        */
152 enum NN_UNIT
153 {
154     NONE =0,
155     BYTES =1,
156     MILLISECONDS =2,
157     PRIORITY =3,
158     BOOLEAN =4,
159 }
160 enum NN_UNIT_NONE = NN_UNIT.NONE;
161 enum NN_UNIT_BYTES = NN_UNIT.BYTES;
162 enum NN_UNIT_MILLISECONDS = NN_UNIT.MILLISECONDS;
163 enum NN_UNIT_PRIORITY = NN_UNIT.PRIORITY;
164 enum NN_UNIT_BOOLEAN = NN_UNIT.BOOLEAN;
165 
166 /*  Structure that is returned from nn_symbol  */
167 align(1) struct nn_symbol_properties
168 {
169     /*  The constant value  */
170     int value;
171     /*  The constant name  */
172     const(char)* name;
173     /*  The constant namespace, or zero for namespaces themselves */
174     int ns;
175     /*  The option type for socket option constants  */
176     int type;
177     /*  The unit for the option value for socket option constants  */
178     int unit;
179 }
180 
181 /*  Fills in nn_symbol_properties structure and returns it's length           */
182 /*  If the index is out-of-range, returns 0                                   */
183 /*  General usage is to start at i=0 and iterate until zero is returned.      */
184 extern (C) int nn_symbol_info (int i, nn_symbol_properties* buf, int buflen);
185 
186 /******************************************************************************/
187 /*  Helper function for shutting down multi-threaded applications.            */
188 /******************************************************************************/
189 extern (C) void nn_term ();
190 
191 
192 /******************************************************************************/
193 /*  Zero-copy support.                                                        */
194 /******************************************************************************/
195 
196 enum NN_MSG= cast(size_t)-1;
197 extern (C) void *nn_allocmsg (size_t size, int type);
198 extern (C) void *nn_reallocmsg (void* msg, size_t size);
199 extern (C) int nn_freemsg (void* msg);
200 
201 /******************************************************************************/
202 /*  Socket definition.                                                        */
203 /******************************************************************************/
204 align(1) struct nn_iovec
205 {
206     void* iov_base;
207     size_t iov_len;
208 }
209 
210 align(1) struct nn_msghdr
211 {
212     nn_iovec* msg_iov;
213     int msg_iovlen;
214     void* msg_control;
215     size_t msg_controllen;
216 }
217 
218 align(1) struct nn_cmsghdr
219 {
220     size_t cmsg_len;
221     int cmsg_level;
222     int cmsg_type;
223 }
224 
225 /** Internal function. Not to be used directly.
226     Use NN_CMSG_NEXTHDR macro instead.
227 */
228 extern (C)  nn_cmsghdr* nn_cmsg_nexthdr_ (const(nn_msghdr)* mhdr,const(nn_cmsghdr)* cmsg);
229 alias NN_CMSG_ALIGN_ = (len) => (len + size_t.sizeof - 1) & cast(size_t) ~(size_t.sizeof - 1);
230 
231 /* POSIX-defined msghdr manipulation. */
232 
233 alias NN_CMSG_FIRSTHDR = (mhdr) => nn_cmsg_nxthdr_ (cast(nn_msghdr*) mhdr, null);
234 
235 alias NN_CMSG_NXTHDR = (mhdr, cmsg) => nn_cmsg_nxthdr_ (cast(nn_msghdr*) mhdr, cast(nn_cmsghdr*) cmsg);
236 
237 alias NN_CMSG_DATA = (cmsg) => cast(ubyte*) ((cast(nn_cmsghdr*) cmsg) + 1);
238 
239 /* Extensions to POSIX defined by RFC 3542.                                   */
240 
241 alias NN_CMSG_SPACE = (len) => (NN_CMSG_ALIGN_ (len) + NN_CMSG_ALIGN_ (nn_cmsghdr.sizeof));
242 
243 alias NN_CMSG_LEN = (len) => (NN_CMSG_ALIGN_ (nn_cmsghdr.sizeof) + (len));
244 
245 
246 /*  SP address families.                                                      */
247 enum AF_SP = 1;
248 enum AF_SP_RAW = 2;
249 
250 /*  Max size of an SP address.                                                */
251 enum NN_SOCKADDR_MAX =128;
252 
253 /*  Socket option levels: Negative numbers are reserved for transports,
254     positive for socket types. */
255 enum NN_SOL_SOCKET =0;
256 
257 /*  Generic socket options (NN_SOL_SOCKET level).                             */
258 enum NN
259 {
260     LINGER=1,
261     SNDBUF =2,
262     RCVBUF =3,
263     SNDTIMEO =4,
264     RCVTIMEO =5,
265     RECONNECT_IVL= 6,
266     RECONNECT_IVL_MAX =7,
267     SNDPRIO =8,
268     RCVPRIO= 9,
269     SNDFD=10,
270     RCVFD =11,
271     DOMAIN =12,
272     PROTOCOL =13,
273     IPV4ONLY =14,
274     SOCKET_NAME=15,
275     RCVMAXSIZE=16,
276     TTL=17,
277 }
278 enum NN_LINGER = NN.LINGER;
279 enum NN_SNDBUF = NN.SNDBUF;
280 enum NN_RCVBUF = NN.RCVBUF;
281 enum NN_SNDTIMEO = NN.SNDTIMEO;
282 enum NN_RCVTIMEO = NN.RCVTIMEO;
283 enum NN_RECONNECT_IVL = NN.RECONNECT_IVL;
284 enum NN_RECONNECT_IVL_MAX = NN.RECONNECT_IVL_MAX;
285 enum NN_SNDPRIO = NN.SNDPRIO;
286 enum NN_RCVPRIO = NN.RCVPRIO;
287 enum NN_SNDFD = NN.SNDFD;
288 enum NN_RCVFD = NN.RCVFD;
289 enum NN_DOMAIN = NN.DOMAIN;
290 enum NN_PROTOCOL = NN.PROTOCOL;
291 enum NN_IPV4ONLY = NN.IPV4ONLY;
292 enum NN_SOCKET_NAME = NN.SOCKET_NAME;
293 enum NN_RCVMAXSIZE = NN.RCVMAXSIZE;
294 enum NN_TTL = NN.TTL;
295 
296 /*  Send/recv options.                                                        */
297 enum NN_DONTWAIT =1;
298 
299 
300 extern (C) int nn_socket(int domain, int protocol);
301 extern (C) int nn_close(int s);
302 extern (C) int nn_setsockopt(int s, int level, int option, const(void)* optval,size_t optvallen);
303 extern (C) int nn_getsockopt(int s, int level, int option, void* optval,size_t* optvallen);
304 extern (C) int nn_bind(int s, const(char)* addr);
305 extern (C) int nn_connect(int s, const(char)* addr);
306 extern (C) int nn_shutdown(int s, int how);
307 extern (C) int nn_send(int s, const(void)* buf, size_t len, int flags);
308 extern (C) int nn_recv(int s, void* buf, size_t len, int flags);
309 extern (C) int nn_sendmsg(int s, nn_msghdr* msghdr, int flags);
310 extern (C) int nn_sendmsg(int s, const(nn_msghdr)* msghdr, int flags);
311 extern (C) int nn_recvmsg(int s,  nn_msghdr* msghdr, int flags);
312 
313 
314 /******************************************************************************/
315 /*  Socket multiplexing support.                                              */
316 /******************************************************************************/
317 
318 enum NN_POLLIN  = 1;
319 enum NN_POLLOUT = 2;
320 
321 align(1) struct nn_pollfd
322 {
323     int fd;
324     short events;
325     short revents;
326 }
327 
328 extern(C) int nn_poll(nn_pollfd* fds, int nfds, int timeout);
329 
330 /******************************************************************************/
331 /*  Built-in support for devices.                                             */
332 /******************************************************************************/
333 
334 extern(C) int nn_device(int s1, int s2);
335 
336 /******************************************************************************/
337 /*  Built-in support for multiplexers.                                        */
338 /******************************************************************************/
339 
340 /******************************************************************************/
341 /*  Built-in support for devices.                                             */
342 /******************************************************************************/
343 
344 extern(C) int nn_tcpmuxd (int port);
345 
346 
347 enum PAIR_H_INCLUDED=1;
348 
349 /**
350     PAIR
351 */
352 enum NN_PROTO_PAIR=1;
353 enum NN_PAIR=(NN_PROTO_PAIR * 16 + 0);
354 
355 enum PIPELINE_H_INCLUDED=1;
356 
357 /**
358     PIPELINE
359 */
360 enum NN_PROTO_PIPELINE=5;
361 enum NN_PUSH=(NN_PROTO_PIPELINE * 16 + 0);
362 enum NN_PULL=(NN_PROTO_PIPELINE * 16 + 1);
363 
364 
365 
366 enum NN_PROTOCOL_INCLUDED=1;
367 struct nn_ctx;
368 enum NN_PIPE
369 {
370     RELEASE=1,
371     PARSED=2,
372     IN=33987,
373     OUT=33988,
374 }
375 struct nn_pipe;
376 struct nn_msg;
377 
378 extern(C)
379 {
380     void nn_pipe_setdata ( nn_pipe *self, void *data);
381     void *nn_pipe_getdata (nn_pipe *self);
382     int nn_pipe_send(nn_pipe *self,  nn_msg *msg);
383     int nn_pipe_recv ( nn_pipe *self, nn_msg *msg);
384     void nn_pipe_getopt ( nn_pipe *self, int level, int option,void *optval, size_t *optvallen);
385 }
386 
387 
388 /******************************************************************************/
389 /*  Base class for all socket types.                                          */
390 /******************************************************************************/
391 
392 /*  Any combination of these events can be returned from 'events' virtual
393     function. */
394 enum  NN_SOCKBASE_EVENT_IN=1;
395 enum NN_SOCKBASE_EVENT_OUT=2;
396 
397 /*  To be implemented by individual socket types. */
398 align(1) struct nn_sockbase_vfptr
399 {
400     extern(C) void function(nn_sockbase*) stop;
401     extern(C) void function(nn_sockbase*) destroy;
402     extern(C) int function(nn_sockbase*,nn_pipe*) add;
403     extern(C) void function(nn_sockbase*, nn_pipe*) rm;
404     extern(C) void function(nn_sockbase*, nn_pipe*) in_;
405     extern(C) void function(nn_sockbase*, nn_pipe*) out_;
406     extern(C) int function(nn_sockbase*) events;
407     extern(C) int function(nn_sockbase*, nn_msg*) send;
408     extern(C) int function(nn_sockbase*, nn_msg*) recv;
409     extern(C) int function(nn_sockbase*, int level, int option,const void* optval, size_t optvallen) setopt;
410     extern(C) int function(nn_sockbase*, int level, int option,void* optval, size_t *optvallen) getopt;
411 }
412 
413 struct nn_sockbase
414 {
415     const(nn_sockbase_vfptr)* vfptr;
416      nn_sock *sock;
417 }
418 
419 /*  Initialise the socket base class. 'hint' is the opaque value passed to the
420     nn_transport's 'create' function. */
421 extern(C) void nn_sockbase_init ( nn_sockbase *self,const  nn_sockbase_vfptr *vfptr, void *hint);
422 
423 /*  Terminate the socket base class. */
424 extern(C) void nn_sockbase_term ( nn_sockbase *self);
425 
426 /*  Call this function when stopping is done. */
427 extern(C) void nn_sockbase_stopped ( nn_sockbase *self);
428 
429 /*  Returns the AIO context associated with the socket. This function is
430     useful when socket type implementation needs to create async objects,
431     such as timers. */
432 extern(C) nn_ctx *nn_sockbase_getctx ( nn_sockbase *self);
433 
434 /*  Retrieve a NN_SOL_SOCKET-level option. */
435 extern(C) int nn_sockbase_getopt (nn_sockbase* self, int option, void* optval, size_t *optvallen);
436 
437 /*  Add some statitistics for socket  */
438 extern(C) void nn_sockbase_stat_increment (nn_sockbase* self, int name,int increment);
439 
440 enum NN_STAT_CURRENT_SND_PRIORITY=401;
441 
442 /******************************************************************************/
443 /*  The socktype class.                                                       */
444 /******************************************************************************/
445 
446 /*  This structure defines a class factory for individual socket types. */
447 
448 /*  Specifies that the socket type can be never used to receive messages. */
449 enum NN_SOCKTYPE_FLAG_NORECV=1;
450 
451 /*  Specifies that the socket type can be never used to send messages. */
452 enum NN_SOCKTYPE_FLAG_NOSEND=2;
453 
454 struct nn_socktype {
455     int domain;
456     int protocol;
457     int flags;
458     int function(void *hint, nn_sockbase **sockbase) create;
459     int function(int socktype) ispeer;
460     nn_list_item* item;
461 };
462 
463 
464 /**
465     PUBSUB
466 */
467 enum NN_PROTO_PUBSUB=2;
468 enum NN_PUB=NN_PROTO_PUBSUB * 16 + 0;
469 enum NN_SUB=NN_PROTO_PUBSUB * 16 + 1;
470 enum NN_SUB_SUBSCRIBE =1;
471 enum NN_SUB_UNSUBSCRIBE=2;
472 
473 
474 /**
475     BUS
476 */
477 enum NN_PROTO_BUS=7;
478 enum NN_BUS=(NN_PROTO_BUS * 16 + 0);
479 
480 /**
481     INPROC
482 */
483 enum NN_INPROC=-1;
484 
485 /**
486     IPC
487 */
488 
489 enum NN_IPC=-2;
490 
491 
492 /**
493     REQREP
494 */
495 enum REQREP_H_INCLUDED=1;
496 enum NN_PROTO_REQREP = 3;
497 
498 enum NN_REQ=NN_PROTO_REQREP * 16 + 0;
499 enum NN_REP=NN_PROTO_REQREP * 16 + 1;
500 
501 enum NN_REQ_RESEND_IVL=1;
502 
503 align(1) union nn_req_handle
504 {
505     int i;
506     void *ptr;
507 };
508 
509 extern(C) int nn_req_send (int s, nn_req_handle hndl, const(void)* buf, size_t len, int flags);
510 extern(C) int nn_req_recv (int s, nn_req_handle *hndl, void *buf, size_t len, int flags);
511 
512 
513 /**
514     TCPMUX
515 */
516 enum NN_TCPMUX = -5;
517 enum NN_TCPMUX_NODELAY = 1;
518 
519 /**
520     WS
521 */
522 enum NN_WS = -4;
523 
524 /*  NN_WS level socket/cmsg options.  Note that only NN_WSMG_TYPE_TEXT and
525     NN_WS_MSG_TYPE_BINARY messages are supported fully by this implementation.
526     Attempting to set other message types is undefined.  */
527 enum NN_WS_MSG_TYPE = 1;
528 
529 /*  WebSocket opcode constants as per RFC 6455 5.2  */
530 enum NN_WS_MSG_TYPE_TEXT = 0x01;
531 enum NN_WS_MSG_TYPE_BINARY = 0x02;
532 
533 /**
534     SURVEY
535 */
536 
537 
538 enum SURVEY_H_INCLUDED=1;
539 enum NN_PROTO_SURVEY=6;
540 
541 enum NN_SURVEYOR=(NN_PROTO_SURVEY * 16 + 2);
542 enum NN_RESPONDENT=(NN_PROTO_SURVEY * 16 + 3);
543 
544 enum NN_SURVEYOR_DEADLINE=1;
545 enum TCP_H_INCLUDED=1;
546 enum NN_TCP=-3;
547 enum NN_TCP_NODELAY=1;
548 struct nn_sock;
549 struct nn_cp;
550 struct nn_ep;
551 
552 struct nn_optset_vfptr
553 {
554     extern (C) void function(nn_optset *self) destroy;
555     extern (C) int function(nn_optset *self, int option, const(void)* optval,size_t optvallen) setopt;
556     extern (C) int function(nn_optset *self, int option, void *optval,size_t *optvallen) getopt;
557 }
558 
559 struct nn_optset
560 {
561     const(nn_optset_vfptr)* vfptr;
562 };
563 
564 
565 struct nn_epbase_vfptr
566 {
567     extern (C) void function(nn_epbase *) stop;
568     extern (C) void function(nn_epbase *) destroy;
569 }
570 
571 struct nn_epbase
572 {
573     const(nn_epbase_vfptr)* vfptr;
574      nn_ep *ep;
575 }
576 
577 /*  Creates a new endpoint. 'hint' parameter is an opaque value that
578     was passed to transport's bind or connect function. */
579 
580 extern(C) void nn_epbase_init ( nn_epbase *self,const  nn_epbase_vfptr *vfptr, void *hint);
581 extern(C) void nn_epbase_stopped ( nn_epbase *self);
582 extern(C) void nn_epbase_term (nn_epbase *self);
583 extern(C) nn_ctx *nn_epbase_getctx ( nn_epbase *self);
584 extern(C) char *nn_epbase_getaddr ( nn_epbase *self);
585 extern(C) void nn_epbase_getopt ( nn_epbase *self, int level, int option,void *optval, size_t *optvallen);
586 extern(C) int nn_epbase_ispeer ( nn_epbase *self, int socktype);
587 extern(C) void nn_epbase_set_error( nn_epbase *self, int errnum);
588 extern(C) void nn_epbase_clear_error( nn_epbase *self);
589 extern(C) void nn_epbase_stat_increment(nn_epbase *self, int name, int increment);
590 
591 
592 enum NN_STAT
593 {
594     ESTABLISHED_CONNECTIONS=101,
595     ACCEPTED_CONNECTIONS    =102,
596     DROPPED_CONNECTIONS     =103,
597     BROKEN_CONNECTIONS      =104,
598     CONNECT_ERRORS          =105,
599     BIND_ERRORS             =106,
600     ACCEPT_ERRORS           =107,
601     CURRENT_CONNECTIONS     =201,
602     INPROGRESS_CONNECTIONS  =202,
603     CURRENT_EP_ERRORS       =203,
604 }
605 
606 enum NN_PIPE_RELEASE=1;
607 enum NN_PIPE_PARSED=2;
608 enum NN_PIPE_IN=33987;
609 enum NN_PIPE_OUT=33988;
610 
611 enum NN_PIPEBASE
612 {
613     RELEASE=1,
614     PARSED=2,
615 }
616 
617 align(1) struct nn_pipebase_vfptr
618 {
619     alias _send=extern(C) int function(nn_pipebase* self, nn_msg* msg);
620     alias _recv=extern(C) int function(nn_pipebase* self,  nn_msg* msg);
621     _send send;
622     _recv recv;
623 }
624 
625 
626 align(1) struct nn_ep_options
627 {
628     int sndprio;
629     int rcvprio;
630     int ipv4only;
631 }
632 
633 align(1) struct nn_pipebase
634 {
635     nn_fsm fsm;
636     const nn_pipebase_vfptr* vfptr;
637     ubyte state;
638     ubyte instate;
639     ubyte outstate;
640     nn_sock *sock;
641     void *data;
642     nn_fsm_event IN;
643     nn_fsm_event OUT;
644     nn_ep_options options;
645 }
646 
647 extern(C) void nn_pipebase_init (nn_pipebase*,const(nn_pipebase_vfptr)* vfptr, nn_epbase* epbase);
648 extern(C) void nn_pipebase_term ( nn_pipebase*);
649 extern(C) int nn_pipebase_start ( nn_pipebase*);
650 extern(C) void nn_pipebase_stop ( nn_pipebase*);
651 extern(C) void nn_pipebase_received ( nn_pipebase*);
652 extern(C) void nn_pipebase_sent ( nn_pipebase*);
653 extern(C) void nn_pipebase_getopt ( nn_pipebase* , int level, int option,void *optval, size_t *optvallen);
654 extern(C) int nn_pipebase_ispeer ( nn_pipebase*, int socktype);
655 extern(C) void nn_pipe_setdata(nn_pipe *self, void *data);
656 extern(C) void *nn_pipe_getdata ( nn_pipe *self);
657 extern(C) int nn_pipe_send ( nn_pipe *self, nn_msg *msg);
658 extern(C) int nn_pipe_recv ( nn_pipe *self, nn_msg *msg);
659 extern(C) void nn_pipe_getopt (nn_pipe *self, int level, int option, void *optval, size_t *optvallen);
660 
661 
662 align(1) struct nn_transport
663 {
664     const(char*) name;
665     int id;
666     extern(C) void function() init;
667     extern(C) void function() term;
668     extern(C) int function(void *hint, nn_epbase **epbase) bind;
669     extern(C) int function(void *hint,  nn_epbase **epbase) connect;
670     extern(C) nn_optset* function() optset;
671     nn_list_item item;
672 }
673 
674 enum NN_FSM_INCLUDED=1;
675 
676 align(1) struct nn_worker;
677 
678 align(1) struct nn_fsm_event
679 {
680     nn_fsm* fsm;
681     int src;
682     void* srcptr;
683     int type;
684     nn_queue_item item;
685 }
686 
687 
688 extern(C) void nn_fsm_event_init(nn_fsm_event *self);
689 extern(C) void nn_fsm_event_term(nn_fsm_event *self);
690 extern(C) int nn_fsm_event_active(nn_fsm_event *self);
691 extern(C) void nn_fsm_event_process(nn_fsm_event *self);
692 
693 
694 /*  Special source for actions. It's negative not to clash with user-defined
695     sources. */
696 enum NN_FSM_ACTION =-2;
697 
698 /*  Actions generated by fsm object. The values are negative not to clash
699     with user-defined actions. */
700 enum NN_FSM_START=-2;
701 enum NN_FSM_STOP =-3;
702 
703 /*  Virtual function to be implemented by the derived class to handle the
704     incoming events. */
705 alias nn_fsm_fn = extern(C) void function(nn_fsm*, int, int, void*);
706 
707 align(1) struct nn_fsm_owner
708 {
709     int src;
710     nn_fsm *fsm;
711 }
712 
713 align(1) struct nn_fsm
714 {
715     nn_fsm_fn fn;
716     nn_fsm_fn shutdown_fn;
717     int state;
718     int src;
719     void *srcptr;
720     nn_fsm *owner;
721     nn_ctx *ctx;
722     nn_fsm_event stopped;
723 }
724 
725 
726 extern(C) void nn_fsm_init_root(nn_fsm *self, nn_fsm_fn fn,nn_fsm_fn shutdown_fn, nn_ctx* ctx);
727 extern(C) void nn_fsm_init(nn_fsm *, nn_fsm_fn fn,nn_fsm_fn shutdown_fn,int src, void *srcptr, nn_fsm* owner);
728 extern(C) void nn_fsm_term(nn_fsm *);
729 extern(C) int nn_fsm_isidle(nn_fsm *);
730 extern(C) void nn_fsm_start(nn_fsm *);
731 extern(C) void nn_fsm_stop(nn_fsm *);
732 extern(C) void nn_fsm_stopped(nn_fsm*, int type);
733 extern(C) void nn_fsm_stopped_noevent(nn_fsm*);
734 extern(C) void nn_fsm_swap_owner(nn_fsm*, nn_fsm_owner* owner);
735 extern(C) nn_worker* nn_fsm_choose_worker(nn_fsm*);
736 extern(C) void nn_fsm_action(nn_fsm*, int type);
737 extern(C) void nn_fsm_raise(nn_fsm*, nn_fsm_event* event, int type);
738 extern(C) void nn_fsm_raiseto(nn_fsm*, nn_fsm* dst, nn_fsm_event* event, int src, int type, void *srcptr);
739 extern(C) void nn_fsm_feed(nn_fsm*, int src, int type, void* srcptr);
740 
741 
742 enum NN_LIST_INCLUDED=1;
743 
744 align(1) struct nn_list_item
745 {
746     nn_list_item* next;
747     nn_list_item* prev;
748 }
749 
750 align(1) struct nn_list
751 {
752     nn_list_item* first;
753     nn_list_item* last;
754 };
755 
756 /*  Undefined value for initializing a list item which is not part of a list. */
757 enum NN_LIST_NOTINLIST = cast(const(nn_list_item)*)-1;
758 
759 /*  Use for initializing a list item statically. */
760 immutable typeof(NN_LIST_NOTINLIST)[2] NN_LIST_ITEM_INITIALIZER=[NN_LIST_NOTINLIST, NN_LIST_NOTINLIST];
761 
762 
763 /*  Initialise the list. */
764 
765 extern(C) void nn_list_init(nn_list*);
766 extern(C) void nn_list_term(nn_list*);
767 extern(C) int nn_list_empty(nn_list*);
768 extern(C) nn_list_item* nn_list_begin(nn_list*);
769 extern(C) nn_list_item* nn_list_end(nn_list*);
770 extern(C) nn_list_item *nn_list_prev(nn_list*,nn_list_item*);
771 extern(C) nn_list_item *nn_list_next(nn_list*,nn_list_item*);
772 extern(C) void nn_list_insert(nn_list*, nn_list_item*, nn_list_item*);
773 extern(C) nn_list_item* nn_list_erase(nn_list*,nn_list_item*);
774 extern(C) void nn_list_item_init(nn_list_item*);
775 extern(C) void nn_list_item_term(nn_list_item*);
776 extern(C) int nn_list_item_isinlist(nn_list_item*);
777 
778 
779 enum NN_QUEUE_INCLUDED = 1;
780 
781 /*  Undefined value for initialising a queue item which is not
782     part of a queue. */
783 const(nn_queue_item)* NN_QUEUE_NOTINQUEUE=cast(const(nn_queue_item)*) -1;
784 
785 
786 /+
787 /*  Use for initialising a queue item statically. */
788 auto NN_QUEUE_ITEM_INITIALIZER()
789 {
790     return [NN_LIST_NOTINQUEUE];
791 }
792 +/
793 
794 align(1) struct nn_queue_item
795 {
796     nn_queue_item *next;
797 }
798 
799 align(1) struct nn_queue
800 {
801     nn_queue_item *head;
802     nn_queue_item *tail;
803 }
804 
805 extern(C) void nn_queue_init(nn_queue*);
806 extern(C) void nn_queue_term(nn_queue*);
807 extern(C) int nn_queue_empty(nn_queue*);
808 extern(C) void nn_queue_push(nn_queue*, nn_queue_item*);
809 extern(C) nn_queue_item *nn_queue_pop( nn_queue*);
810 extern(C) void nn_queue_item_init(nn_queue_item*);
811 extern(C) void nn_queue_item_term(nn_queue_item*);
812 extern(C) int nn_queue_item_isinqueue(nn_queue_item*);
813 
814 
815 
816 /*  Returns the symbol name (e.g. "NN_REQ") and value at a specified index.   */
817 /*  If the index is out-of-range, returns null and sets errno to EINVAL       */
818 /*  General usage is to start at i=0 and iterate until null is returned.      */
819 extern(C) const(char)* nn_symbol (int i, int *value);
820 
821 
822 /*  Associates opaque pointer to protocol-specific data with the pipe. */
823 extern(C) void nn_pipe_setdata (nn_pipe *self, void *data);
824 
825 /*  Retrieves the opaque pointer associated with the pipe. */
826 extern(C) void *nn_pipe_getdata (nn_pipe* self);
827 
828 /*  Send the message to the pipe. If successful, pipe takes ownership of the
829     messages. */
830 extern(C) int nn_pipe_send (nn_pipe* self, nn_msg* msg);
831 
832 /*  Receive a message from a pipe. 'msg' should not be initialised prior to
833     the call. It will be initialised when the call succeeds. */
834 extern(C) int nn_pipe_recv (nn_pipe* self, nn_msg* msg);
835 
836 /*  Get option for pipe. Mostly useful for endpoint-specific options  */
837 extern(C) void nn_pipe_getopt (nn_pipe* self, int level, int option, void* optval, size_t* optvallen);
838 
839 
840 /******************************************************************************/
841 /*  Base class for all socket types.                                          */
842 /******************************************************************************/
843 
844 /*  Initialise the socket base class. 'hint' is the opaque value passed to the
845     nn_transport's 'create' function. */
846 extern(C) void nn_sockbase_init (nn_sockbase* self, const(nn_sockbase_vfptr)* vfptr, void* hint);
847 
848 /*  Terminate the socket base class. */
849 extern(C) void nn_sockbase_term (nn_sockbase* self);
850 
851 /*  Call this function when stopping is done. */
852 extern(C) void nn_sockbase_stopped (nn_sockbase* self);
853 
854 /*  Returns the AIO context associated with the socket. This function is
855     useful when socket type implementation needs to create async objects,
856     such as timers. */
857 extern(C) nn_ctx *nn_sockbase_getctx (nn_sockbase *self);
858 
859 /*  Retrieve a NN_SOL_SOCKET-level option. */
860 extern(C) int nn_sockbase_getopt (nn_sockbase *self, int option, void *optval, size_t *optvallen);
861 
862 /*  Add some statistics for socket  */
863 extern(C) void nn_sockbase_stat_increment (nn_sockbase *self, int name, int increment);
864 
865 /*  Creates a new endpoint. 'hint' parameter is an opaque value that
866     was passed to transport's bind or connect function. */
867 extern(C) void nn_epbase_init (nn_epbase* self, const(nn_epbase_vfptr)* vfptr, void *hint);
868 
869 /*  Notify the user that stopping is done. */
870 extern(C) void nn_epbase_stopped (nn_epbase* self);
871 
872 /*  Terminate the epbase object. */
873 extern(C) void nn_epbase_term (nn_epbase* self);
874 
875 /*  Returns the AIO context associated with the endpoint. */
876 extern(C) nn_ctx *nn_epbase_getctx (nn_epbase* self);
877 
878 /*  Returns the address string associated with this endpoint. */
879 extern(C) const(char*) nn_epbase_getaddr (nn_epbase* self);
880 
881 /*  Retrieve value of a socket option. */
882 extern(C) void nn_epbase_getopt (nn_epbase* self, int level, int option, void *optval, size_t *optvallen);
883 
884 /*  Returns 1 is the specified socket type is a valid peer for this socket,
885     or 0 otherwise. */
886 extern(C) int nn_epbase_ispeer (nn_epbase* self, int socktype);
887 
888 /*  Notifies a monitoring system the error on this endpoint  */
889 extern(C) void nn_epbase_set_error(nn_epbase* self, int errnum);
890 
891 /*  Notifies a monitoring system that error is gone  */
892 extern(C) void nn_epbase_clear_error(nn_epbase* self);
893 
894 /*  Increments statistics counters in the socket structure  */
895 extern(C) void nn_epbase_stat_increment(nn_epbase* self, int name, int increment);
896 
897 
898 enum NN_STAT_ESTABLISHED_CONNECTIONS =101;
899 enum NN_STAT_ACCEPTED_CONNECTIONS    =102;
900 enum NN_STAT_DROPPED_CONNECTIONS     =103;
901 enum NN_STAT_BROKEN_CONNECTIONS      =104;
902 enum NN_STAT_CONNECT_ERRORS          =105;
903 enum NN_STAT_BIND_ERRORS             =106;
904 enum NN_STAT_ACCEPT_ERRORS           =107;
905 
906 enum NN_STAT_CURRENT_CONNECTIONS     =201;
907 enum NN_STAT_INPROGRESS_CONNECTIONS  =202;
908 enum NN_STAT_CURRENT_EP_ERRORS       =203;
909 
910 
911 /******************************************************************************/
912 /*  The base class for pipes.                                                 */
913 /******************************************************************************/
914 
915 /*  Pipe represents one "connection", i.e. perfectly ordered uni- or
916     bi-directional stream of messages. One endpoint can create multiple pipes
917     (for example, bound TCP socket is an endpoint, individual accepted TCP
918     connections are represented by pipes. */
919 
920 
921 /*  This value is returned by pipe's send and recv functions to signalise that
922     more sends/recvs are not possible at the moment. From that moment on,
923     the core will stop invoking the function. To re-establish the message
924     flow nn_pipebase_received (respectively nn_pipebase_sent) should
925     be called. */
926 enum NN_PIPEBASE_RELEASE=1;
927 
928 /*  Specifies that received message is already split into header and body.
929     This flag is used only by inproc transport to avoid merging and re-splitting
930     the messages passed with a single process. */
931 enum NN_PIPEBASE_PARSED=2;
932 
933 /*  Initialise the pipe.  */
934 extern(C) void nn_pipebase_init (nn_pipebase *self, const(nn_pipebase_vfptr)* vfptr, nn_epbase *epbase);
935 
936 /*  Terminate the pipe. */
937 extern(C) void nn_pipebase_term (nn_pipebase *self);
938 
939 /*  Call this function once the connection is established. */
940 extern(C) int nn_pipebase_start (nn_pipebase *self);
941 
942 /*  Call this function once the connection is broken. */
943 extern(C) void nn_pipebase_stop (nn_pipebase *self);
944 
945 /*  Call this function when new message was fully received. */
946 extern(C) void nn_pipebase_received (nn_pipebase *self);
947 
948 /*  Call this function when current outgoing message was fully sent. */
949 extern(C) void nn_pipebase_sent (nn_pipebase *self);
950 
951 /*  Retrieve value of a socket option. */
952 extern(C) void nn_pipebase_getopt (nn_pipebase *self, int level, int option, void *optval, size_t *optvallen);
953 
954 /*  Returns 1 is the specified socket type is a valid peer for this socket,
955     or 0 otherwise. */
956 extern(C) int nn_pipebase_ispeer (nn_pipebase *self, int socktype);
957 
958 
959 /*
960     Copyright (c) 2012-2014 250bpm s.r.o.  All rights reserved.
961     Copyright (c) 2013 GoPivotal, Inc.  All rights reserved.
962 
963     Permission is hereby granted, free of charge, to any person obtaining a copy
964     of this software and associated documentation files (the "Software"),
965     to deal in the Software without restriction, including without limitation
966     the rights to use, copy, modify, merge, publish, distribute, sublicense,
967     and/or sell copies of the Software, and to permit persons to whom
968     the Software is furnished to do so, subject to the following conditions:
969 
970     The above copyright notice and this permission notice shall be included
971     in all copies or substantial portions of the Software.
972 
973     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
974     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
975     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
976     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
977     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
978     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
979     IN THE SOFTWARE.
980 */