Example #1
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);
}
JNIEXPORT jint JNICALL
Java_org_zeromq_czmq_Zsys__1_1ipv6 (JNIEnv *env, jclass c)
{
    jint ipv6_ = (jint) zsys_ipv6 ();
    return ipv6_;
}
Example #3
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;
}
Example #4
0
///
//  Return use of IPv6 for zsock instances.
int QmlZsysAttached::ipv6 () {
    return zsys_ipv6 ();
};
Example #5
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);
}
Example #6
0
///
//  Return use of IPv6 for zsock instances.
int QZsys::ipv6 ()
{
    int rv = zsys_ipv6 ();
    return rv;
}