JNIEXPORT jstring JNICALL Java_org_zeromq_czmq_Zsys__1_1interface (JNIEnv *env, jclass c) { char *interface_ = (char *) zsys_interface (); jstring return_string_ = (*env)->NewStringUTF (env, interface_); return return_string_; }
static void s_self_configure (self_t *self, int port_nbr) { assert (port_nbr); self->port_nbr = port_nbr; s_self_prepare_udp (self); zstr_send (self->pipe, self->hostname); if (streq (self->hostname, "")) zsys_error ("No broadcast interface found, (ZSYS_INTERFACE=%s)", zsys_interface ()); }
static void zyre_node_recv_beacon (zyre_node_t *self) { // Get IP address and beacon of peer char *ipaddress = zstr_recv (self->beacon); zframe_t *frame = zframe_recv (self->beacon); if (ipaddress == NULL) return; // Interrupted // Ignore anything that isn't a valid beacon beacon_t beacon; memset (&beacon, 0, sizeof (beacon_t)); if (zframe_size (frame) == sizeof (beacon_t)) memcpy (&beacon, zframe_data (frame), zframe_size (frame)); zframe_destroy (&frame); if (beacon.version != BEACON_VERSION) return; // Garbage beacon, ignore it zuuid_t *uuid = zuuid_new (); zuuid_set (uuid, beacon.uuid); if (beacon.port) { char endpoint [100]; const char *iface = zsys_interface (); if (zsys_ipv6 () && iface && !streq (iface, "") && !streq (iface, "*")) sprintf (endpoint, "tcp://%s%%%s:%d", ipaddress, iface, ntohs (beacon.port)); else sprintf (endpoint, "tcp://%s:%d", ipaddress, ntohs (beacon.port)); zyre_peer_t *peer = zyre_node_require_peer (self, uuid, endpoint); zyre_peer_refresh (peer, self->evasive_timeout, self->expired_timeout); } else { // Zero port means peer is going away; remove it if // we had any knowledge of it already zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup ( self->peers, zuuid_str (uuid)); if (peer) zyre_node_remove_peer (self, peer); } zuuid_destroy (&uuid); zstr_free (&ipaddress); }
static int zyre_node_start (zyre_node_t *self) { if (self->beacon_port) { // Start beacon discovery // ------------------------------------------------------------------ assert (!self->beacon); self->beacon = zactor_new (zbeacon, NULL); if (!self->beacon) return 1; // Not possible to start beacon if (self->verbose) zsock_send (self->beacon, "s", "VERBOSE"); } else { // Start gossip discovery // ------------------------------------------------------------------ // If application didn't set an endpoint explicitly, grab ephemeral // port on all available network interfaces. if (!self->endpoint) { const char *iface = zsys_interface (); if (streq (iface, "")) iface = "*"; self->port = zsock_bind (self->inbox, "tcp://%s:*", iface); assert (self->port > 0); // Die on bad interface or port exhaustion char *hostname = zsys_hostname (); self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port); zstr_free (&hostname); } assert (self->gossip); zstr_sendx (self->gossip, "PUBLISH", zuuid_str (self->uuid), self->endpoint, NULL); // Start polling on zgossip zpoller_add (self->poller, self->gossip); // Start polling on inbox zpoller_add(self->poller, self->inbox); } return 0; }
static void s_self_prepare_udp (self_t *self) { // Create our UDP socket if (self->udpsock) zsys_udp_close (self->udpsock); self->hostname [0] = 0; self->udpsock = zsys_udp_new (false); if (self->udpsock == INVALID_SOCKET) return; // Get the network interface fro ZSYS_INTERFACE or else use first // broadcast interface defined on system. ZSYS_INTERFACE=* means // use INADDR_ANY + INADDR_BROADCAST. const char *iface = zsys_interface (); in_addr_t bind_to = 0; in_addr_t send_to = 0; if (streq (iface, "*")) { // Wildcard means bind to INADDR_ANY and send to INADDR_BROADCAST bind_to = INADDR_ANY; send_to = INADDR_BROADCAST; } else { // Look for matching interface, or first ziflist item ziflist_t *iflist = ziflist_new (); assert (iflist); const char *name = ziflist_first (iflist); while (name) { if (streq (iface, name) || streq (iface, "")) { // Using inet_addr instead of inet_aton or inet_atop // because these are not supported in Win XP send_to = inet_addr (ziflist_broadcast (iflist)); bind_to = inet_addr (ziflist_address (iflist)); if (self->verbose) zsys_info ("zbeacon: interface=%s address=%s broadcast=%s", name, ziflist_address (iflist), ziflist_broadcast (iflist)); break; // iface is known, so allow it } name = ziflist_next (iflist); } ziflist_destroy (&iflist); } if (bind_to) { self->broadcast.sin_family = AF_INET; self->broadcast.sin_port = htons (self->port_nbr); self->broadcast.sin_addr.s_addr = send_to; inaddr_t address = self->broadcast; address.sin_addr.s_addr = bind_to; // Bind to the port on all interfaces #if (defined (__WINDOWS__)) inaddr_t sockaddr = address; #elif (defined (__APPLE__)) inaddr_t sockaddr = self->broadcast; sockaddr.sin_addr.s_addr = htons (INADDR_ANY); #else inaddr_t sockaddr = self->broadcast; #endif // Bind must succeed; we treat failure here as a hard violation (assert) if (bind (self->udpsock, (struct sockaddr *) &sockaddr, sizeof (inaddr_t))) zsys_socket_error ("bind"); // Get our hostname so we can send it back to the API if (getnameinfo ((struct sockaddr *) &address, sizeof (inaddr_t), self->hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) { if (self->verbose) zsys_info ("zbeacon: configured, hostname=%s", self->hostname); } } }
int zyre_peer_connect (zyre_peer_t *self, zuuid_t *from, const char *endpoint, uint64_t expired_timeout) { assert (self); assert (!self->connected); // Create new outgoing socket (drop any messages in transit) self->mailbox = zsock_new (ZMQ_DEALER); if (!self->mailbox) return -1; // Null when we're shutting down // Set our own identity on the socket so that receiving node // knows who each message came from. Note that we cannot use // the UUID directly as the identity since it may contain a // zero byte at the start, which libzmq does not like for // historical and arguably bogus reasons that it nonetheless // enforces. byte routing_id [ZUUID_LEN + 1] = { 1 }; memcpy (routing_id + 1, zuuid_data (from), ZUUID_LEN); int rc = zmq_setsockopt (zsock_resolve (self->mailbox), ZMQ_IDENTITY, routing_id, ZUUID_LEN + 1); assert (rc == 0); // Set a high-water mark that allows for reasonable activity zsock_set_sndhwm (self->mailbox, expired_timeout * 100); // Send messages immediately or return EAGAIN zsock_set_sndtimeo (self->mailbox, 0); // If the peer is a link-local IPv6 address but the interface is not set, // use ZSYS_INTERFACE_ADDRESS if provided zrex_t *rex = zrex_new (NULL); char endpoint_iface [NI_MAXHOST] = {0}; if (zsys_ipv6 () && zsys_interface () && strlen(zsys_interface ()) && !streq (zsys_interface (), "*") && zrex_eq (rex, endpoint, "^tcp://(fe80[^%]+)(:\\d+)$")) { const char *hostname, *port; zrex_fetch (rex, &hostname, &port, NULL); strcat (endpoint_iface, "tcp://"); strcat (endpoint_iface, hostname); strcat (endpoint_iface, "%"); strcat (endpoint_iface, zsys_interface ()); strcat (endpoint_iface, port); } else strcat (endpoint_iface, endpoint); zrex_destroy (&rex); // Connect through to peer node rc = zsock_connect (self->mailbox, "%s", endpoint_iface); if (rc != 0) { zsys_debug ("(%s) cannot connect to endpoint=%s", self->origin, endpoint_iface); zsock_destroy (&self->mailbox); return -1; } if (self->verbose) zsys_info ("(%s) connect to peer: endpoint=%s", self->origin, endpoint_iface); self->endpoint = strdup (endpoint_iface); self->connected = true; self->ready = false; return 0; }
/// // Return network interface to use for broadcasts, or "" if none was set. const QString QmlZsysAttached::interface () { return QString (zsys_interface ()); };
void zyre_node_actor (zsock_t *pipe, void *args) { // Create node instance to pass around zyre_node_t *self = zyre_node_new (pipe, args); if (!self) // Interrupted return; // Signal actor successfully initialized zsock_signal (self->pipe, 0); // Loop until the agent is terminated one way or another int64_t reap_at = zclock_mono () + REAP_INTERVAL; while (!self->terminated) { // Start beacon as soon as we can if (self->beacon && self->port <= 0) { // Our hostname is provided by zbeacon zsock_send(self->beacon, "si", "CONFIGURE", self->beacon_port); char *hostname = zstr_recv(self->beacon); // Is UDP broadcast interface available? if (!streq(hostname, "")) { if (zsys_ipv6()) self->port = zsock_bind(self->inbox, "tcp://%s%%%s:*", zsys_ipv6_address(), zsys_interface()); else self->port = zsock_bind(self->inbox, "tcp://%s:*", hostname); if (self->port > 0) { assert(!self->endpoint); // If caller set this, we'd be using gossip if (streq(zsys_interface(), "*")) { char *hostname = zsys_hostname(); self->endpoint = zsys_sprintf("tcp://%s:%d", hostname, self->port); zstr_free(&hostname); } else { self->endpoint = strdup(zsock_endpoint(self->inbox)); } // Set broadcast/listen beacon beacon_t beacon; beacon.protocol[0] = 'Z'; beacon.protocol[1] = 'R'; beacon.protocol[2] = 'E'; beacon.version = BEACON_VERSION; beacon.port = htons(self->port); zuuid_export(self->uuid, beacon.uuid); zsock_send(self->beacon, "sbi", "PUBLISH", (byte *)&beacon, sizeof(beacon_t), self->interval); zsock_send(self->beacon, "sb", "SUBSCRIBE", (byte *) "ZRE", 3); zpoller_add(self->poller, self->beacon); // Start polling on inbox zpoller_add(self->poller, self->inbox); } } zstr_free(&hostname); } int timeout = (int) (reap_at - zclock_mono ()); if (timeout > REAP_INTERVAL) timeout = REAP_INTERVAL; else if (timeout < 0) timeout = 0; zsock_t *which = (zsock_t *) zpoller_wait (self->poller, timeout); if (which == self->pipe) zyre_node_recv_api (self); else if (which == self->inbox) zyre_node_recv_peer (self); else if (self->beacon && (void *) which == self->beacon) zyre_node_recv_beacon (self); else if (self->gossip && (zactor_t *) which == self->gossip) zyre_node_recv_gossip (self); else if (zpoller_terminated (self->poller)) break; // Interrupted, check before expired else if (zpoller_expired (self->poller)) { if (zclock_mono () >= reap_at) { void *item; reap_at = zclock_mono () + REAP_INTERVAL; // Ping all peers and reap any expired ones for (item = zhash_first (self->peers); item != NULL; item = zhash_next (self->peers)) zyre_node_ping_peer (zhash_cursor (self->peers), item, self); } } } zyre_node_destroy (&self); }
static int zyre_node_start (zyre_node_t *self) { if (self->beacon_port) { // Start beacon discovery // ------------------------------------------------------------------ assert (!self->beacon); self->beacon = zactor_new (zbeacon, NULL); if (!self->beacon) return 1; // Not possible to start beacon if (self->verbose) zsock_send (self->beacon, "s", "VERBOSE"); // Our hostname is provided by zbeacon zsock_send (self->beacon, "si", "CONFIGURE", self->beacon_port); char *hostname = zstr_recv (self->beacon); if (streq (hostname, "")) return -1; // No UDP broadcast interface available self->port = zsock_bind (self->inbox, "tcp://%s:*", hostname); zstr_free (&hostname); assert (self->port > 0); // Die on bad interface or port exhaustion assert (!self->endpoint); // If caller set this, we'd be using gossip self->endpoint = strdup (zsock_endpoint (self->inbox)); // Set broadcast/listen beacon beacon_t beacon; beacon.protocol [0] = 'Z'; beacon.protocol [1] = 'R'; beacon.protocol [2] = 'E'; beacon.version = BEACON_VERSION; beacon.port = htons (self->port); zuuid_export (self->uuid, beacon.uuid); zsock_send (self->beacon, "sbi", "PUBLISH", (byte *) &beacon, sizeof (beacon_t), self->interval); zsock_send (self->beacon, "sb", "SUBSCRIBE", (byte *) "ZRE", 3); zpoller_add (self->poller, self->beacon); } else { // Start gossip discovery // ------------------------------------------------------------------ // If application didn't set an endpoint explicitly, grab ephemeral // port on all available network interfaces. if (!self->endpoint) { const char *iface = zsys_interface (); if (streq (iface, "")) iface = "*"; self->port = zsock_bind (self->inbox, "tcp://%s:*", iface); assert (self->port > 0); // Die on bad interface or port exhaustion char *hostname = zsys_hostname (); self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port); zstr_free (&hostname); } assert (self->gossip); zstr_sendx (self->gossip, "PUBLISH", zuuid_str (self->uuid), self->endpoint, NULL); // Start polling on zgossip zpoller_add (self->poller, self->gossip); } // Start polling on inbox zpoller_add (self->poller, self->inbox); return 0; }
/// // Return network interface to use for broadcasts, or "" if none was set. const QString QZsys::interface () { const QString rv = QString (zsys_interface ()); return rv; }