Esempio n. 1
0
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_;
}
Esempio n. 2
0
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 ());
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
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);
        }
    }
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
///
//  Return network interface to use for broadcasts, or "" if none was set.
const QString QmlZsysAttached::interface () {
    return QString (zsys_interface ());
};
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
}