int nn_cinproc_create (struct nn_ep *ep) { struct nn_cinproc *self; self = nn_alloc (sizeof (struct nn_cinproc), "cinproc"); alloc_assert (self); nn_ep_tran_setup (ep, &nn_cinproc_ops, self); nn_ins_item_init (&self->item, ep); nn_fsm_init_root (&self->fsm, nn_cinproc_handler, nn_cinproc_shutdown, nn_ep_getctx (ep)); self->state = NN_CINPROC_STATE_IDLE; nn_list_init (&self->sinprocs); nn_ep_stat_increment (ep, NN_STAT_INPROGRESS_CONNECTIONS, 1); /* 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); return 0; }
MgErr ftw_nanomsg_reserve(struct ftw_socket_callsite **inst) { static int callsite = 0; /* Preconditions expected of LabVIEW. */ ftw_assert(inst); /* Creates a list of socket instances for each CLFN callsite. */ if (*inst == NULL) { callsite++; ftw_debug("Reserving Socket Creation Callsite %d", callsite); *inst = ftw_malloc(sizeof(struct ftw_socket_callsite)); ftw_assert(*inst); nn_mutex_init(&(*inst)->sync); nn_mutex_lock(&(*inst)->sync); nn_list_init(&(*inst)->active_sockets); (*inst)->id = callsite; (*inst)->lifetime_sockets = 0; nn_mutex_unlock(&(*inst)->sync); } else { ftw_assert_unreachable("Reserve happened twice; this is a problem with LabVIEW."); } return mgNoErr; }
int nn_binproc_create (void *hint, struct nn_epbase **epbase) { int rc; struct nn_binproc *self; self = nn_alloc (sizeof (struct nn_binproc), "binproc"); alloc_assert (self); nn_ins_item_init (&self->item, &nn_binproc_vfptr, hint); nn_fsm_init_root (&self->fsm, nn_binproc_handler, nn_binproc_shutdown, nn_epbase_getctx (&self->item.epbase)); self->state = NN_BINPROC_STATE_IDLE; nn_list_init (&self->sinprocs); /* Start the state machine. */ nn_fsm_start (&self->fsm); /* Register the inproc endpoint into a global repository. */ rc = nn_ins_bind (&self->item, nn_binproc_connect); if (nn_slow (rc < 0)) { nn_list_term (&self->sinprocs); /* TODO: Now, this is ugly! We are getting the state machine into the idle state manually. How should it be done correctly? */ self->fsm.state = 1; nn_fsm_term (&self->fsm); nn_ins_item_term (&self->item); nn_free (self); return rc; } *epbase = &self->item.epbase; return 0; }
struct nn_binproc *nn_binproc_create (void *hint) { struct nn_binproc *self; size_t sz; self = nn_alloc (sizeof (struct nn_binproc), "binproc"); alloc_assert (self); nn_epbase_init (&self->epbase, &nn_binproc_vfptr, hint); nn_fsm_init_root (&self->fsm, nn_binproc_handler, nn_epbase_getctx (&self->epbase)); self->state = NN_BINPROC_STATE_IDLE; nn_list_init (&self->sinprocs); nn_list_item_init (&self->item); sz = sizeof (self->protocol); nn_epbase_getopt (&self->epbase, NN_SOL_SOCKET, NN_PROTOCOL, &self->protocol, &sz); nn_assert (sz == sizeof (self->protocol)); self->connects = 0; /* Start the state machine. */ nn_fsm_start (&self->fsm); return self; }
int nn_bipc_create (void *hint, struct nn_epbase **epbase) { struct nn_bipc *self; /* 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_epbase_getctx (&self->epbase)); self->state = NN_BIPC_STATE_IDLE; 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_sockbase_init (struct nn_sockbase *self, const struct nn_sockbase_vfptr *vfptr) { int rc; /* Make sure that at least one message direction is supported. */ nn_assert (!(vfptr->flags & NN_SOCKBASE_FLAG_NOSEND) || !(vfptr->flags & NN_SOCKBASE_FLAG_NORECV)); /* Open the NN_SNDFD and NN_RCVFD efds. Do so, only if the socket type supports send/recv, as appropriate. */ if (vfptr->flags & NN_SOCKBASE_FLAG_NOSEND) memset (&self->sndfd, 0xcd, sizeof (self->sndfd)); else { rc = nn_efd_init (&self->sndfd); if (nn_slow (rc < 0)) return rc; } if (vfptr->flags & NN_SOCKBASE_FLAG_NORECV) memset (&self->rcvfd, 0xcd, sizeof (self->rcvfd)); else { rc = nn_efd_init (&self->rcvfd); if (nn_slow (rc < 0)) { if (!(vfptr->flags & NN_SOCKBASE_FLAG_NOSEND)) nn_efd_term (&self->sndfd); return rc; } } memset (&self->termsem, 0xcd, sizeof (self->termsem)); rc = nn_cp_init (&self->cp); if (nn_slow (rc < 0)) { if (!(vfptr->flags & NN_SOCKBASE_FLAG_NORECV)) nn_efd_term (&self->rcvfd); if (!(vfptr->flags & NN_SOCKBASE_FLAG_NOSEND)) nn_efd_term (&self->sndfd); return rc; } self->vfptr = vfptr; self->flags = 0; nn_clock_init (&self->clock); nn_list_init (&self->eps); self->eid = 1; /* Default values for NN_SOL_SOCKET options. */ self->domain = -1; self->protocol = -1; self->linger = 1000; self->sndbuf = 128 * 1024; self->rcvbuf = 128 * 1024; self->sndtimeo = -1; self->rcvtimeo = -1; self->reconnect_ivl = 100; self->reconnect_ivl_max = 0; self->sndprio = 8; self->rcvprio = 8; return 0; }
void nn_priolist_init (struct nn_priolist *self) { int i; for (i = 0; i != NN_PRIOLIST_SLOTS; ++i) { nn_list_init (&self->slots [i].pipes); self->slots [i].current = NULL; } self->current = -1; }
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; }
void nn_sws_init (struct nn_sws *self, int src, struct nn_epbase *epbase, struct nn_fsm *owner) { nn_fsm_init (&self->fsm, nn_sws_handler, nn_sws_shutdown, src, self, owner); self->state = NN_SWS_STATE_IDLE; nn_wshdr_init (&self->wshdr, NN_SWS_SRC_HANDSHAKE, &self->fsm); self->usock = NULL; self->usock_owner.src = -1; self->usock_owner.fsm = NULL; nn_pipebase_init (&self->pipebase, &nn_sws_pipebase_vfptr, epbase); self->instate = -1; nn_list_init (&self->inmsg_array); self->outstate = -1; nn_msg_init (&self->outmsg, 0); self->continuing = 0; nn_fsm_event_init (&self->done); }
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_btcp_create (void *hint, struct nn_epbase **epbase) { int rc; struct nn_btcp *self; const char *addr; const char *end; const char *pos; struct sockaddr_storage ss; size_t sslen; int ipv4only; size_t ipv4onlylen; /* Allocate the new endpoint object. */ self = nn_alloc (sizeof (struct nn_btcp), "btcp"); alloc_assert (self); /* Initalise the epbase. */ nn_epbase_init (&self->epbase, &nn_btcp_epbase_vfptr, hint); addr = nn_epbase_getaddr (&self->epbase); /* Parse the port. */ end = addr + strlen (addr); pos = strrchr (addr, ':'); if (nn_slow (!pos)) { nn_epbase_term (&self->epbase); return -EINVAL; } ++pos; rc = nn_port_resolve (pos, end - pos); if (nn_slow (rc < 0)) { nn_epbase_term (&self->epbase); return -EINVAL; } /* Check whether IPv6 is to be used. */ ipv4onlylen = sizeof (ipv4only); nn_epbase_getopt (&self->epbase, NN_SOL_SOCKET, NN_IPV4ONLY, &ipv4only, &ipv4onlylen); nn_assert (ipv4onlylen == sizeof (ipv4only)); /* Parse the address. */ rc = nn_iface_resolve (addr, pos - addr - 1, ipv4only, &ss, &sslen); if (nn_slow (rc < 0)) { nn_epbase_term (&self->epbase); return -ENODEV; } /* Initialise the structure. */ nn_fsm_init_root (&self->fsm, nn_btcp_handler, nn_btcp_shutdown, nn_epbase_getctx (&self->epbase)); self->state = NN_BTCP_STATE_IDLE; nn_usock_init (&self->usock, NN_BTCP_SRC_USOCK, &self->fsm); self->atcp = NULL; nn_list_init (&self->atcps); /* Start the state machine. */ nn_fsm_start (&self->fsm); /* Return the base class as an out parameter. */ *epbase = &self->epbase; return 0; }
/* Initialize a socket. A hold is placed on the initialized socket for the caller as well. */ int nn_sock_init (struct nn_sock *self, struct nn_socktype *socktype, int fd) { int rc; int i; /* Make sure that at least one message direction is supported. */ nn_assert (!(socktype->flags & NN_SOCKTYPE_FLAG_NOSEND) || !(socktype->flags & NN_SOCKTYPE_FLAG_NORECV)); /* Create the AIO context for the SP socket. */ nn_ctx_init (&self->ctx, nn_global_getpool (), nn_sock_onleave); /* Initialise the state machine. */ nn_fsm_init_root (&self->fsm, nn_sock_handler, nn_sock_shutdown, &self->ctx); self->state = NN_SOCK_STATE_INIT; /* Open the NN_SNDFD and NN_RCVFD efds. Do so, only if the socket type supports send/recv, as appropriate. */ if (socktype->flags & NN_SOCKTYPE_FLAG_NOSEND) memset (&self->sndfd, 0xcd, sizeof (self->sndfd)); else { rc = nn_efd_init (&self->sndfd); if (nn_slow (rc < 0)) return rc; } if (socktype->flags & NN_SOCKTYPE_FLAG_NORECV) memset (&self->rcvfd, 0xcd, sizeof (self->rcvfd)); else { rc = nn_efd_init (&self->rcvfd); if (nn_slow (rc < 0)) { if (!(socktype->flags & NN_SOCKTYPE_FLAG_NOSEND)) nn_efd_term (&self->sndfd); return rc; } } nn_sem_init (&self->termsem); nn_sem_init (&self->relesem); if (nn_slow (rc < 0)) { if (!(socktype->flags & NN_SOCKTYPE_FLAG_NORECV)) nn_efd_term (&self->rcvfd); if (!(socktype->flags & NN_SOCKTYPE_FLAG_NOSEND)) nn_efd_term (&self->sndfd); return rc; } self->holds = 1; /* Callers hold. */ self->flags = 0; nn_clock_init (&self->clock); nn_list_init (&self->eps); nn_list_init (&self->sdeps); self->eid = 1; /* Default values for NN_SOL_SOCKET options. */ self->linger = 1000; self->sndbuf = 128 * 1024; self->rcvbuf = 128 * 1024; self->rcvmaxsize = 1024 * 1024; self->sndtimeo = -1; self->rcvtimeo = -1; self->reconnect_ivl = 100; self->reconnect_ivl_max = 0; self->ep_template.sndprio = 8; self->ep_template.rcvprio = 8; self->ep_template.ipv4only = 1; /* Initialize statistic entries */ self->statistics.established_connections = 0; self->statistics.accepted_connections = 0; self->statistics.dropped_connections = 0; self->statistics.broken_connections = 0; self->statistics.connect_errors = 0; self->statistics.bind_errors = 0; self->statistics.accept_errors = 0; self->statistics.messages_sent = 0; self->statistics.messages_received = 0; self->statistics.bytes_sent = 0; self->statistics.bytes_received = 0; self->statistics.current_connections = 0; self->statistics.inprogress_connections = 0; self->statistics.current_snd_priority = 0; self->statistics.current_ep_errors = 0; /* Should be pretty much enough space for just the number */ sprintf(self->socket_name, "%d", fd); /* The transport-specific options are not initialised immediately, rather, they are allocated later on when needed. */ for (i = 0; i != NN_MAX_TRANSPORT; ++i) self->optsets [i] = NULL; /* Create the specific socket type itself. */ rc = socktype->create ((void*) self, &self->sockbase); errnum_assert (rc == 0, -rc); self->socktype = socktype; /* Launch the state machine. */ nn_ctx_enter (&self->ctx); nn_fsm_start (&self->fsm); nn_ctx_leave (&self->ctx); return 0; }
static void nn_global_init (void) { int i; #if defined NN_HAVE_WINDOWS WSADATA data; int rc; #endif /* Check whether the library was already initialised. If so, do nothing. */ if (self.socks) return; /* On Windows, initialise the socket library. */ #if defined NN_HAVE_WINDOWS rc = WSAStartup (MAKEWORD (2, 2), &data); nn_assert (rc == 0); nn_assert (LOBYTE (data.wVersion) == 2 && HIBYTE (data.wVersion) == 2); #endif /* Initialise the memory allocation subsystem. */ nn_alloc_init (); /* Seed the pseudo-random number generator. */ nn_random_seed (); /* Allocate the global table of SP sockets. */ self.socks = nn_alloc ((sizeof (struct nn_sock*) * NN_MAX_SOCKETS) + (sizeof (uint16_t) * NN_MAX_SOCKETS), "socket table"); alloc_assert (self.socks); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.socks [i] = NULL; self.nsocks = 0; self.flags = 0; /* Allocate the stack of unused file descriptors. */ self.unused = (uint16_t*) (self.socks + NN_MAX_SOCKETS); alloc_assert (self.unused); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.unused [i] = NN_MAX_SOCKETS - i - 1; /* Initialise other parts of the global state. */ nn_list_init (&self.transports); nn_list_init (&self.socktypes); /* Plug in individual transports. */ nn_global_add_transport (nn_inproc); #if !defined NN_HAVE_WINDOWS nn_global_add_transport (nn_ipc); #endif nn_global_add_transport (nn_tcp); /* Plug in individual socktypes. */ nn_global_add_socktype (nn_pair_socktype); nn_global_add_socktype (nn_xpair_socktype); nn_global_add_socktype (nn_pub_socktype); nn_global_add_socktype (nn_sub_socktype); nn_global_add_socktype (nn_rep_socktype); nn_global_add_socktype (nn_req_socktype); nn_global_add_socktype (nn_xrep_socktype); nn_global_add_socktype (nn_xreq_socktype); nn_global_add_socktype (nn_push_socktype); nn_global_add_socktype (nn_xpush_socktype); nn_global_add_socktype (nn_pull_socktype); nn_global_add_socktype (nn_xpull_socktype); nn_global_add_socktype (nn_respondent_socktype); nn_global_add_socktype (nn_surveyor_socktype); nn_global_add_socktype (nn_xrespondent_socktype); nn_global_add_socktype (nn_xsurveyor_socktype); nn_global_add_socktype (nn_bus_socktype); nn_global_add_socktype (nn_xbus_socktype); /* Start the worker threads. */ nn_pool_init (&self.pool); }
void nn_ins_init (void) { nn_mutex_init (&self.sync); nn_list_init (&self.bound); nn_list_init (&self.connected); }
static void nn_global_init (void) { int i; char *envvar; int rc; char *addr; #if defined NN_HAVE_WINDOWS WSADATA data; #endif /* Check whether the library was already initialised. If so, do nothing. */ if (self.socks) return; /* On Windows, initialise the socket library. */ #if defined NN_HAVE_WINDOWS rc = WSAStartup (MAKEWORD (2, 2), &data); nn_assert (rc == 0); nn_assert (LOBYTE (data.wVersion) == 2 && HIBYTE (data.wVersion) == 2); #endif /* Initialise the memory allocation subsystem. */ nn_alloc_init (); /* Seed the pseudo-random number generator. */ nn_random_seed (); /* Allocate the global table of SP sockets. */ self.socks = nn_alloc ((sizeof (struct nn_sock*) * NN_MAX_SOCKETS) + (sizeof (uint16_t) * NN_MAX_SOCKETS), "socket table"); alloc_assert (self.socks); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.socks [i] = NULL; self.nsocks = 0; self.flags = 0; /* Print connection and accepting errors to the stderr */ envvar = getenv("NN_PRINT_ERRORS"); /* any non-empty string is true */ self.print_errors = envvar && *envvar; /* Print socket statistics to stderr */ envvar = getenv("NN_PRINT_STATISTICS"); self.print_statistics = envvar && *envvar; /* Allocate the stack of unused file descriptors. */ self.unused = (uint16_t*) (self.socks + NN_MAX_SOCKETS); alloc_assert (self.unused); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.unused [i] = NN_MAX_SOCKETS - i - 1; /* Initialise other parts of the global state. */ nn_list_init (&self.transports); nn_list_init (&self.socktypes); /* Plug in individual transports. */ nn_global_add_transport (nn_inproc); nn_global_add_transport (nn_ipc); nn_global_add_transport (nn_tcp); nn_global_add_transport (nn_ws); nn_global_add_transport (nn_tcpmux); /* Plug in individual socktypes. */ nn_global_add_socktype (nn_pair_socktype); nn_global_add_socktype (nn_xpair_socktype); nn_global_add_socktype (nn_pub_socktype); nn_global_add_socktype (nn_sub_socktype); nn_global_add_socktype (nn_xpub_socktype); nn_global_add_socktype (nn_xsub_socktype); nn_global_add_socktype (nn_rep_socktype); nn_global_add_socktype (nn_req_socktype); nn_global_add_socktype (nn_xrep_socktype); nn_global_add_socktype (nn_xreq_socktype); nn_global_add_socktype (nn_push_socktype); nn_global_add_socktype (nn_xpush_socktype); nn_global_add_socktype (nn_pull_socktype); nn_global_add_socktype (nn_xpull_socktype); nn_global_add_socktype (nn_respondent_socktype); nn_global_add_socktype (nn_surveyor_socktype); nn_global_add_socktype (nn_xrespondent_socktype); nn_global_add_socktype (nn_xsurveyor_socktype); nn_global_add_socktype (nn_bus_socktype); nn_global_add_socktype (nn_xbus_socktype); /* Start the worker threads. */ nn_pool_init (&self.pool); /* Start FSM */ nn_fsm_init_root (&self.fsm, nn_global_handler, nn_global_shutdown, &self.ctx); self.state = NN_GLOBAL_STATE_IDLE; nn_ctx_init (&self.ctx, nn_global_getpool (), NULL); nn_timer_init (&self.stat_timer, NN_GLOBAL_SRC_STAT_TIMER, &self.fsm); nn_fsm_start (&self.fsm); /* Initializing special sockets. */ addr = getenv ("NN_STATISTICS_SOCKET"); if (addr) { self.statistics_socket = nn_global_create_socket (AF_SP, NN_PUB); errno_assert (self.statistics_socket >= 0); rc = nn_global_create_ep (self.statistics_socket, addr, 0); errno_assert (rc >= 0); } else { self.statistics_socket = -1; } addr = getenv ("NN_APPLICATION_NAME"); if (addr) { strncpy (self.appname, addr, 63); self.appname[63] = '\0'; } else { /* No cross-platform way to find out application binary. Also, MSVC suggests using _getpid() instead of getpid(), however, it's not clear whether the former is supported by older versions of Windows/MSVC. */ #if defined _MSC_VER #pragma warning (push) #pragma warning (disable:4996) #endif sprintf (self.appname, "nanomsg.%d", getpid()); #if defined _MSC_VER #pragma warning (pop) #endif } addr = getenv ("NN_HOSTNAME"); if (addr) { strncpy (self.hostname, addr, 63); self.hostname[63] = '\0'; } else { rc = gethostname (self.hostname, 63); errno_assert (rc == 0); self.hostname[63] = '\0'; } }
static void nn_inproc_ctx_init (void) { nn_list_init (&self.bound); nn_list_init (&self.connected); }
void nn_dist_init (struct nn_dist *self) { self->count = 0; nn_list_init (&self->pipes); }