static int nn_req_create (void *hint, struct nn_sockbase **sockbase) { struct nn_req *self; self = nn_alloc (sizeof (struct nn_req), "socket (req)"); alloc_assert (self); nn_req_init (self, &nn_req_sockbase_vfptr, hint); *sockbase = &self->xreq.sockbase; return 0; }
static int nn_sub_create (void *hint, struct nn_sockbase **sockbase) { struct nn_sub *self; self = nn_alloc (sizeof (struct nn_sub), "socket (sub)"); alloc_assert (self); nn_sub_init (self, &nn_sub_sockbase_vfptr, hint); *sockbase = &self->sockbase; return 0; }
static void nn_btcp_start_accepting (struct nn_btcp *self) { nn_assert (self->atcp == NULL); /* Allocate new atcp state machine. */ self->atcp = nn_alloc (sizeof (struct nn_atcp), "atcp"); alloc_assert (self->atcp); nn_atcp_init (self->atcp, NN_BTCP_SRC_ATCP, &self->epbase, &self->fsm); /* Start waiting for a new incoming connection. */ nn_atcp_start (self->atcp, &self->usock); }
static void nn_bws_start_accepting (struct nn_bws *self) { nn_assert (self->aws == NULL); /* Allocate new aws state machine. */ self->aws = nn_alloc (sizeof (struct nn_aws), "aws"); alloc_assert (self->aws); nn_aws_init (self->aws, NN_BWS_SRC_AWS, &self->epbase, &self->fsm); /* Start waiting for a new incoming connection. */ nn_aws_start (self->aws, &self->usock); }
static void nn_bipc_start_accepting (struct nn_bipc *self) { nn_assert (self->aipc == NULL); /* Allocate new aipc state machine. */ self->aipc = nn_alloc (sizeof (struct nn_aipc), "aipc"); alloc_assert (self->aipc); nn_aipc_init (self->aipc, NN_BIPC_SRC_AIPC, &self->epbase, &self->fsm); /* Start waiting for a new incoming connection. */ nn_aipc_start (self->aipc, &self->usock); }
static struct nn_optset *nn_ws_optset () { struct nn_ws_optset *optset; optset = nn_alloc (sizeof (struct nn_ws_optset), "optset (ws)"); alloc_assert (optset); optset->base.vfptr = &nn_ws_optset_vfptr; /* Default values for WebSocket options. */ optset->msg_type = NN_WS_MSG_TYPE_BINARY; return &optset->base; }
static struct nn_optset *nn_ws_optset () { struct nn_ws_optset *optset; optset = nn_alloc (sizeof (struct nn_ws_optset), "optset (ws)"); alloc_assert (optset); optset->base.vfptr = &nn_ws_optset_vfptr; /* Default values for WebSocket options. */ optset->placeholder = 1000; return &optset->base; }
static int nn_xpush_add (struct nn_sockbase *self, struct nn_pipe *pipe) { struct nn_xpush *xpush; struct nn_xpush_data *data; xpush = nn_cont (self, struct nn_xpush, sockbase); data = nn_alloc (sizeof (struct nn_xpush_data), "pipe data (push)"); alloc_assert (data); nn_pipe_setdata (pipe, data); nn_lb_add (&xpush->lb, pipe, &data->lb, self->sndprio); return 0; }
static struct nn_optset *nn_tcp_optset () { struct nn_tcp_optset *optset; optset = nn_alloc (sizeof (struct nn_tcp_optset), "optset (tcp)"); alloc_assert (optset); optset->base.vfptr = &nn_tcp_optset_vfptr; /* Default values for TCP socket options. */ optset->nodelay = 0; return &optset->base; }
static struct nn_optset *nn_libfabric_optset () { struct nn_libfabric_optset *optset; optset = nn_alloc (sizeof (struct nn_libfabric_optset), "optset (libfabric)"); alloc_assert (optset); optset->base.vfptr = &nn_libfabric_optset_vfptr; /* Default values for LIBFABRIC socket options. */ optset->nodelay = 0; return &optset->base; }
/* Allocate a new message chunk, append it to message array, and return pointer to its buffer. */ static void *nn_msg_chunk_new (size_t size, struct nn_list *msg_array) { struct msg_chunk *self; self = nn_alloc (sizeof (struct msg_chunk), "msg_chunk"); alloc_assert (self); nn_chunkref_init (&self->chunk, size); nn_list_item_init (&self->item); nn_list_insert (msg_array, &self->item, nn_list_end (msg_array)); return nn_chunkref_data (&self->chunk); }
static int nn_xpull_add (struct nn_sockbase *self, struct nn_pipe *pipe) { struct nn_xpull *xpull; struct nn_xpull_data *data; xpull = nn_cont (self, struct nn_xpull, sockbase); data = nn_alloc (sizeof (struct nn_xpull_data), "pipe data (pull)"); alloc_assert (data); nn_pipe_setdata (pipe, data); nn_fq_add (&xpull->fq, pipe, &data->fq, 8); return 0; }
void nn_binproc_connect (struct nn_binproc *self, struct nn_cinproc *peer) { struct nn_sinproc *sinproc; nn_assert (self->state == NN_BINPROC_STATE_ACTIVE); sinproc = nn_alloc (sizeof (struct nn_sinproc), "sinproc"); alloc_assert (sinproc); nn_sinproc_init (sinproc, NN_BINPROC_SRC_SINPROC, &self->epbase, &self->fsm); nn_list_insert (&self->sinprocs, &sinproc->item, nn_list_end (&self->sinprocs)); nn_sinproc_connect (sinproc, &peer->fsm); }
int nn_tcpmuxd (int port) { int rc; int tcp_listener; int ipc_listener; int opt; struct sockaddr_in tcp_addr; struct sockaddr_un ipc_addr; struct nn_tcpmuxd_ctx *ctx; /* Start listening on the specified TCP port. */ tcp_listener = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); errno_assert (tcp_listener >= 0); opt = 1; rc = setsockopt (tcp_listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); errno_assert (rc == 0); memset (&tcp_addr, 0, sizeof (tcp_addr)); tcp_addr.sin_family = AF_INET; tcp_addr.sin_port = htons (port); tcp_addr.sin_addr.s_addr = INADDR_ANY; rc = bind (tcp_listener, (struct sockaddr*) &tcp_addr, sizeof (tcp_addr)); errno_assert (rc == 0); rc = listen (tcp_listener, 100); errno_assert (rc == 0); /* Start listening for incoming IPC connections. */ ipc_addr.sun_family = AF_UNIX; snprintf (ipc_addr.sun_path, sizeof (ipc_addr.sun_path), "/tmp/tcpmux-%d.ipc", (int) port); unlink (ipc_addr.sun_path); ipc_listener = socket (AF_UNIX, SOCK_STREAM, 0); errno_assert (ipc_listener >= 0); rc = bind (ipc_listener, (struct sockaddr*) &ipc_addr, sizeof (ipc_addr)); errno_assert (rc == 0); rc = listen (ipc_listener, 100); errno_assert (rc == 0); /* Allocate a context for the daemon. */ ctx = nn_alloc (sizeof (struct nn_tcpmuxd_ctx), "tcpmuxd context"); alloc_assert (ctx); ctx->tcp_listener = tcp_listener; ctx->ipc_listener = ipc_listener; nn_list_init (&ctx->conns); /* Run the daemon in a dedicated thread. */ nn_thread_init (&ctx->thread, nn_tcpmuxd_routine, ctx); return 0; }
int nn_xbus_add (struct nn_sockbase *self, struct nn_pipe *pipe) { struct nn_xbus *xbus; struct nn_xbus_data *data; xbus = nn_cont (self, struct nn_xbus, sockbase); data = nn_alloc (sizeof (struct nn_xbus_data), "pipe data (xbus)"); alloc_assert (data); nn_fq_add (&xbus->inpipes, pipe, &data->initem, 8); nn_dist_add (&xbus->outpipes, pipe, &data->outitem); nn_pipe_setdata (pipe, data); return 0; }
int nn_xpair_create (struct nn_sockbase **sockbase) { int rc; struct nn_xpair *self; self = nn_alloc (sizeof (struct nn_xpair), "socket (pair)"); alloc_assert (self); rc = nn_xpair_init (self, &nn_xpair_sockbase_vfptr); if (rc < 0) { nn_free (self); return rc; } *sockbase = &self->sockbase; return 0; }
static int nn_req_create (struct nn_sockbase **sockbase) { int rc; struct nn_req *self; self = nn_alloc (sizeof (struct nn_req), "socket (req)"); alloc_assert (self); rc = nn_req_init (self, &nn_req_sockbase_vfptr); if (rc < 0) { nn_free (self); return rc; } *sockbase = &self->xreq.sockbase; return 0; }
static int nn_tcp_bind (const char *addr, void *hint, struct nn_epbase **epbase) { int rc; struct nn_bstream *bstream; bstream = nn_alloc (sizeof (struct nn_bstream), "bstream (tcp)"); alloc_assert (bstream); rc = nn_bstream_init (bstream, addr, hint, nn_tcp_binit, NN_TCP_BACKLOG); if (nn_slow (rc != 0)) { nn_free (bstream); return rc; } *epbase = &bstream->epbase; return 0; }
int nn_xsurveyor_add (struct nn_sockbase *self, struct nn_pipe *pipe) { struct nn_xsurveyor *xsurveyor; struct nn_xsurveyor_data *data; xsurveyor = nn_cont (self, struct nn_xsurveyor, sockbase); data = nn_alloc (sizeof (struct nn_xsurveyor_data), "pipe data (xsurveyor)"); alloc_assert (data); data->pipe = pipe; nn_fq_add (&xsurveyor->inpipes, pipe, &data->initem, 8); nn_dist_add (&xsurveyor->outpipes, pipe, &data->outitem); nn_pipe_setdata (pipe, data); return 0; }
int nn_global_create_socket (int domain, int protocol) { int rc; int s; struct nn_list_item *it; struct nn_socktype *socktype; struct nn_sock *sock; /* The function is called with nn_glock held */ /* Only AF_SP and AF_SP_RAW domains are supported. */ if (nn_slow (domain != AF_SP && domain != AF_SP_RAW)) { return -EAFNOSUPPORT; } /* If socket limit was reached, report error. */ if (nn_slow (self.nsocks >= NN_MAX_SOCKETS)) { return -EMFILE; } /* Find an empty socket slot. */ s = self.unused [NN_MAX_SOCKETS - self.nsocks - 1]; /* Find the appropriate socket type. */ for (it = nn_list_begin (&self.socktypes); it != nn_list_end (&self.socktypes); it = nn_list_next (&self.socktypes, it)) { socktype = nn_cont (it, struct nn_socktype, item); if (socktype->domain == domain && socktype->protocol == protocol) { /* Instantiate the socket. */ sock = nn_alloc (sizeof (struct nn_sock), "sock"); alloc_assert (sock); rc = nn_sock_init (sock, socktype, s); if (rc < 0) return rc; /* Adjust the global socket table. */ self.socks [s] = sock; ++self.nsocks; return s; } } /* Specified socket type wasn't found. */ return -EINVAL; }
void nn_msgqueue_init (struct nn_msgqueue *self, size_t maxmem) { struct nn_msgqueue_chunk *chunk; self->count = 0; self->mem = 0; self->maxmem = maxmem; chunk = nn_alloc (sizeof (struct nn_msgqueue_chunk), "msgqueue chunk"); alloc_assert (chunk); chunk->next = NULL; self->out.chunk = chunk; self->out.pos = 0; self->in.chunk = chunk; self->in.pos = 0; self->cache = NULL; }
static int nn_ipc_connect (const char *addr, void *hint, struct nn_epbase **epbase) { int rc; struct nn_cstream *cstream; /* TODO: Check the syntax of the address here! */ cstream = nn_alloc (sizeof (struct nn_cstream), "cstream (ipc)"); alloc_assert (cstream); rc = nn_cstream_init (cstream, addr, hint, nn_ipc_csockinit, nn_ipc_cresolve); if (nn_slow (rc != 0)) { nn_free (cstream); return rc; } *epbase = &cstream->epbase; return 0; }
static void nn_binproc_connect (struct nn_ins_item *self, struct nn_ins_item *peer) { struct nn_binproc *binproc; struct nn_cinproc *cinproc; struct nn_sinproc *sinproc; binproc = nn_cont (self, struct nn_binproc, item); cinproc = nn_cont (peer, struct nn_cinproc, item); nn_assert (binproc->state == NN_BINPROC_STATE_ACTIVE); sinproc = nn_alloc (sizeof (struct nn_sinproc), "sinproc"); alloc_assert (sinproc); nn_sinproc_init (sinproc, NN_BINPROC_SRC_SINPROC, &binproc->item.epbase, &binproc->fsm); nn_list_insert (&binproc->sinprocs, &sinproc->item, nn_list_end (&binproc->sinprocs)); nn_sinproc_connect (sinproc, &cinproc->fsm); }
static int nn_tcp_connect (const char *addr, void *hint, struct nn_epbase **epbase) { int rc; const char *end; const char *pos; struct nn_cstream *cstream; /* Check the syntax of the address here. First, check whether port number is OK. */ end = addr + strlen (addr); pos = strrchr (addr, ':'); if (!pos) return -EINVAL; ++pos; rc = nn_addr_parse_port (pos, end - pos); if (rc < 0) return rc; /* Now check whether local address, in any, is valid. */ pos = strchr (addr, ';'); if (pos) { rc = nn_addr_parse_local (addr, pos - addr, NN_ADDR_IPV4ONLY, NULL, NULL); if (rc < 0) return rc; } /* Create the async object to handle the connection. */ cstream = nn_alloc (sizeof (struct nn_cstream), "cstream (tcp)"); alloc_assert (cstream); rc = nn_cstream_init (cstream, addr, hint, nn_tcp_csockinit, nn_tcp_cresolve); if (nn_slow (rc != 0)) { nn_free (cstream); return rc; } *epbase = &cstream->epbase; return 0; }
static int nn_xsub_add (struct nn_sockbase *self, struct nn_pipe *pipe) { struct nn_xsub *xsub; struct nn_xsub_data *data; int rcvprio; size_t sz; xsub = nn_cont (self, struct nn_xsub, sockbase); sz = sizeof (rcvprio); nn_pipe_getopt (pipe, NN_SOL_SOCKET, NN_RCVPRIO, &rcvprio, &sz); nn_assert (sz == sizeof (rcvprio)); nn_assert (rcvprio >= 1 && rcvprio <= 16); data = nn_alloc (sizeof (struct nn_xsub_data), "pipe data (sub)"); alloc_assert (data); nn_pipe_setdata (pipe, data); nn_fq_add (&xsub->fq, &data->fq, pipe, rcvprio); return 0; }
static int nn_xpush_add (struct nn_sockbase *self, struct nn_pipe *pipe) { struct nn_xpush *xpush; struct nn_xpush_data *data; int sndprio; size_t sz; xpush = nn_cont (self, struct nn_xpush, sockbase); sz = sizeof (sndprio); nn_pipe_getopt (pipe, NN_SOL_SOCKET, NN_SNDPRIO, &sndprio, &sz); nn_assert (sz == sizeof (sndprio)); nn_assert (sndprio >= 1 && sndprio <= 16); data = nn_alloc (sizeof (struct nn_xpush_data), "pipe data (push)"); alloc_assert (data); nn_pipe_setdata (pipe, data); nn_lb_add (&xpush->lb, pipe, &data->lb, sndprio); return 0; }
int nn_bipc_create (void *hint, struct nn_epbase **epbase) { struct nn_bipc *self; int reconnect_ivl; int reconnect_ivl_max; size_t sz; /* Allocate the new endpoint object. */ self = nn_alloc (sizeof (struct nn_bipc), "bipc"); alloc_assert (self); /* Initialise the structure. */ nn_epbase_init (&self->epbase, &nn_bipc_epbase_vfptr, hint); nn_fsm_init_root (&self->fsm, nn_bipc_handler, nn_bipc_shutdown, nn_epbase_getctx (&self->epbase)); self->state = NN_BIPC_STATE_IDLE; sz = sizeof (reconnect_ivl); nn_epbase_getopt (&self->epbase, NN_SOL_SOCKET, NN_RECONNECT_IVL, &reconnect_ivl, &sz); nn_assert (sz == sizeof (reconnect_ivl)); sz = sizeof (reconnect_ivl_max); nn_epbase_getopt (&self->epbase, NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, &reconnect_ivl_max, &sz); nn_assert (sz == sizeof (reconnect_ivl_max)); if (reconnect_ivl_max == 0) reconnect_ivl_max = reconnect_ivl; nn_backoff_init (&self->retry, NN_BIPC_SRC_RECONNECT_TIMER, reconnect_ivl, reconnect_ivl_max, &self->fsm); nn_usock_init (&self->usock, NN_BIPC_SRC_USOCK, &self->fsm); self->aipc = NULL; nn_list_init (&self->aipcs); /* Start the state machine. */ nn_fsm_start (&self->fsm); /* Return the base class as an out parameter. */ *epbase = &self->epbase; return 0; }
int nn_xreq_add (struct nn_sockbase *self, struct nn_pipe *pipe) { int rc; struct nn_xreq *xreq; struct nn_xreq_data *data; int sndprio; size_t sz; xreq = nn_cont (self, struct nn_xreq, sockbase); sz = sizeof (sndprio); nn_pipe_getopt (pipe, NN_SOL_SOCKET, NN_SNDPRIO, &sndprio, &sz); nn_assert (sz == sizeof (sndprio)); nn_assert (sndprio >= 1 && sndprio <= 16); data = nn_alloc (sizeof (struct nn_xreq_data), "pipe data (req)"); alloc_assert (data); nn_pipe_setdata (pipe, data); nn_lb_add (&xreq->lb, pipe, &data->lb, sndprio); nn_fq_add (&xreq->fq, pipe, &data->fq, 8); return 0; }
static void nn_binproc_connect (struct nn_ins_item *self, struct nn_ins_item *peer) { struct nn_binproc *binproc; struct nn_cinproc *cinproc; struct nn_sinproc *sinproc; binproc = nn_cont (self, struct nn_binproc, item); cinproc = nn_cont (peer, struct nn_cinproc, item); nn_assert_state (binproc, NN_BINPROC_STATE_ACTIVE); sinproc = nn_alloc (sizeof (struct nn_sinproc), "sinproc"); alloc_assert (sinproc); nn_sinproc_init (sinproc, NN_BINPROC_SRC_SINPROC, binproc->item.ep, &binproc->fsm); nn_list_insert (&binproc->sinprocs, &sinproc->item, nn_list_end (&binproc->sinprocs)); nn_sinproc_connect (sinproc, &cinproc->fsm); nn_ep_stat_increment (binproc->item.ep, NN_STAT_ACCEPTED_CONNECTIONS, 1); }
int nn_cinproc_create (void *hint, struct nn_epbase **epbase) { struct nn_cinproc *self; self = nn_alloc (sizeof (struct nn_cinproc), "cinproc"); alloc_assert (self); nn_ins_item_init (&self->item, &nn_cinproc_vfptr, hint); nn_fsm_init_root (&self->fsm, nn_cinproc_handler, nn_cinproc_shutdown, nn_epbase_getctx (&self->item.epbase)); self->state = NN_CINPROC_STATE_IDLE; nn_sinproc_init (&self->sinproc, NN_CINPROC_SRC_SINPROC, &self->item.epbase, &self->fsm); /* Start the state machine. */ nn_fsm_start (&self->fsm); /* Register the inproc endpoint into a global repository. */ nn_ins_connect (&self->item, nn_cinproc_connect); *epbase = &self->item.epbase; return 0; }