예제 #1
0
파일: zyre_node.c 프로젝트: mjhowell/zyre
void
zyre_node_engine (void *args, zctx_t *ctx, void *pipe)
{
    //  Create node instance to pass around
    zyre_node_t *self = zyre_node_new (ctx, pipe);
    if (!self)                  //  Interrupted
        return;
    zsocket_signal (self->pipe);

    uint64_t reap_at = zclock_time () + REAP_INTERVAL;
    zpoller_t *poller = zpoller_new (
        self->pipe, self->inbox, zbeacon_socket (self->beacon), NULL);

    while (!zpoller_terminated (poller)) {
        if (self->terminated)
            break;
        int timeout = (int) (reap_at - zclock_time ());
        assert (timeout <= REAP_INTERVAL);
        if (timeout < 0)
            timeout = 0;
        void *which = zpoller_wait (poller, timeout);
        if (which == self->pipe)
            zyre_node_recv_api (self);
        else
        if (which == self->inbox)
            zyre_node_recv_peer (self);
        else
        if (which == zbeacon_socket (self->beacon))
            zyre_node_recv_beacon (self);
        else
        if (zpoller_expired(poller)) {
            if (zclock_time () >= reap_at) {
                reap_at = zclock_time () + REAP_INTERVAL;
                //  Ping all peers and reap any expired ones
                zhash_foreach (self->peers, zyre_node_ping_peer, self);
            }
        }
        else
        if (zpoller_terminated(poller))
            break;
        else
            // This should never happen
            assert(false);
    }
    zpoller_destroy (&poller);
    zyre_node_destroy (&self);
}
예제 #2
0
파일: zsocket.c 프로젝트: AxelVoitier/czmq
void
zsocket_test (bool verbose)
{
    printf (" * zsocket (deprecated): ");

    //  @selftest
    zctx_t *ctx = zctx_new ();
    assert (ctx);

    //  Create a detached thread, let it run
    char *interf = "127.0.0.1";
    char *domain = "localhost";
    int service = 5560;

    void *writer = zsocket_new (ctx, ZMQ_PUSH);
    assert (writer);
    void *reader = zsocket_new (ctx, ZMQ_PULL);
    assert (reader);
    assert (streq (zsocket_type_str (writer), "PUSH"));
    assert (streq (zsocket_type_str (reader), "PULL"));
    int rc = zsocket_bind (writer, "tcp://%s:%d", interf, service);
    assert (rc == service);

#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (3, 2, 0))
    //  Check unbind
    rc = zsocket_unbind (writer, "tcp://%s:%d", interf, service);
    assert (rc == 0);

    //  In some cases and especially when running under Valgrind, doing
    //  a bind immediately after an unbind causes an EADDRINUSE error.
    //  Even a short sleep allows the OS to release the port for reuse.
    zclock_sleep (100);

    //  Bind again
    rc = zsocket_bind (writer, "tcp://%s:%d", interf, service);
    assert (rc == service);
#endif

    rc = zsocket_connect (reader, "tcp://%s:%d", domain, service);
    assert (rc == 0);
    zstr_send (writer, "HELLO");
    char *message = zstr_recv (reader);
    assert (message);
    assert (streq (message, "HELLO"));
    free (message);

    //  Test binding to ports
    int port = zsocket_bind (writer, "tcp://%s:*", interf);
    assert (port >= ZSOCKET_DYNFROM && port <= ZSOCKET_DYNTO);

    assert (zsocket_poll (writer, 100) == false);

    //  Test error state when connecting to an invalid socket type
    //  ('txp://' instead of 'tcp://', typo intentional)
    rc = zsocket_connect (reader, "txp://%s:%d", domain, service);
    assert (rc == -1);

    //  Test sending frames to socket
    rc = zsocket_sendmem (writer, "ABC", 3, ZFRAME_MORE);
    assert (rc == 0);
    rc = zsocket_sendmem (writer, "DEFG", 4, 0);
    assert (rc == 0);

    zframe_t *frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "ABC"));
    assert (zframe_more (frame));
    zframe_destroy (&frame);

    frame = zframe_recv (reader);
    assert (frame);
    assert (zframe_streq (frame, "DEFG"));
    assert (!zframe_more (frame));
    zframe_destroy (&frame);

    rc = zsocket_signal (writer);
    assert (rc == 0);
    rc = zsocket_wait (reader);
    assert (rc == 0);

    zsocket_destroy (ctx, reader);
    zsocket_destroy (ctx, writer);
    zctx_destroy (&ctx);
    //  @end

    printf ("OK\n");
}
예제 #3
0
void PrimeWorker::Work(zctx_t *ctx, void *pipe) {
	
	printf("PrimeWorker started.\n");
	
	mBackend = zsocket_new(ctx, ZMQ_DEALER);
	void* frontend = zsocket_new(ctx, ZMQ_DEALER);
	void* input = zsocket_new(ctx, ZMQ_SUB);
	mServer = zsocket_new(ctx, ZMQ_ROUTER);
	mSignals = zsocket_new(ctx, ZMQ_PUB);
	
	zsocket_set_sndhwm(mBackend, 1*1000*1000);
	
	int err = 0;
	err = zsocket_bind(mServer, "tcp://*:%d", mServerPort);
	if(!err)
		printf("zsocket_bind(mServer, tcp://*:*) failed.\n");
	
	err = zsocket_bind(mSignals, "tcp://*:%d", mSignalPort);
	if(!err)
		printf("zsocket_bind(mSignals, tcp://*:*) failed.\n");
	
	printf("PrimeWorker: mServerPort=%d mSignalPort=%d\n", mServerPort, mSignalPort);
	
	err = zsocket_connect(mBackend, "tcp://localhost:8888");
	assert(!err);
	
	err = zsocket_connect(frontend, "tcp://localhost:7777");
	assert(!err);
	
	err = zsocket_connect(input, "inproc://bitcoin");
	assert(!err);
	
	const char one[2] = {1, 0};
	zsocket_set_subscribe(input, one);
	
	zloop_t* wloop = zloop_new();
	
	zmq_pollitem_t item_input = {input, 0, ZMQ_POLLIN, 0};
	err = zloop_poller(wloop, &item_input, &PrimeWorker::InvokeInput, this);
	assert(!err);
	
	zmq_pollitem_t item_server = {mServer, 0, ZMQ_POLLIN, 0};
	err = zloop_poller(wloop, &item_server, &PrimeWorker::InvokeRequest, this);
	assert(!err);
	
	zmq_pollitem_t item_frontend = {frontend, 0, ZMQ_POLLIN, 0};
	err = zloop_poller(wloop, &item_frontend, &PrimeWorker::InvokeRequest, this);
	assert(!err);
	
	err = zloop_timer(wloop, 60000, 0, &PrimeWorker::InvokeTimerFunc, this);
	assert(err >= 0);
	
	zsocket_signal(pipe);
	
	zloop_start(wloop);
	
	zloop_destroy(&wloop);
	
	zsocket_destroy(ctx, mServer);
	zsocket_destroy(ctx, mSignals);
	zsocket_destroy(ctx, mBackend);
	zsocket_destroy(ctx, frontend);
	zsocket_destroy(ctx, input);
	
	zsocket_signal(pipe);
	
	printf("PrimeWorker exited.\n");
	
}
예제 #4
0
파일: zproxy.c 프로젝트: TangCheng/czmq
static void
s_proxy_task (void *args, zctx_t *ctx, void *command_pipe)
{
    //  Confirm to API that we've started up
    zsocket_signal (command_pipe);
    zproxy_t *self = (zproxy_t *) args;
    //  Capture socket, if not NULL, receives all data
    void *capture = NULL;

    //  Create poller to work on all three sockets
    zpoller_t *poller = zpoller_new (self->frontend, self->backend, command_pipe, NULL);

    bool stopped = false;
    while (!stopped) {
        //  Wait for activity on any polled socket, and read incoming message
        void *which = zpoller_wait (poller, -1);
        zmq_msg_t msg;
        zmq_msg_init (&msg);
        int send_flags;         //  Flags for outgoing message

        if (which && zmq_recvmsg (which, &msg, 0) != -1) {
            send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0;
            if (which == self->frontend || which == self->backend) {
                void *output = which == self->frontend?
                    self->backend: self->frontend;

                //  Loop on all waiting messages, since polling adds a
                //  non-trivial cost per message, especially on OS/X
                while (true) {
                    if (capture) {
                        zmq_msg_t dup;
                        zmq_msg_init (&dup);
                        zmq_msg_copy (&dup, &msg);
                        if (zmq_sendmsg (capture, &dup, send_flags) == -1)
                            zmq_msg_close (&dup);
                    }
                    if (zmq_sendmsg (output, &msg, send_flags) == -1) {
                        zmq_msg_close (&msg);
                        break;
                    }
                    if (zmq_recvmsg (which, &msg, ZMQ_DONTWAIT) == -1)
                        break;      //  Presumably EAGAIN
                    send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0;
                }
            }
            else
            if (which == command_pipe) {
                char command [10] = { 0 };
                assert (zmq_msg_size (&msg) < 10);
                memcpy (command, zmq_msg_data (&msg), zmq_msg_size (&msg));

                //  Execute API command
                if (streq (command, "PAUSE")) {
                    zpoller_destroy (&poller);
                    poller = zpoller_new (command_pipe, NULL);
                }
                else
                if (streq (command, "RESUME")) {
                    zpoller_destroy (&poller);
                    poller = zpoller_new (self->frontend, self->backend, command_pipe, NULL);
                }
                else
                if (streq (command, "CAPTURE")) {
                    //  Capture flow is always PUSH-to-PULL
                    capture = zsocket_new (self->ctx, ZMQ_PUSH);
                    char *endpoint = zstr_recv (command_pipe);
                    if (capture) {
                        int rc = zsocket_connect (capture, "%s", endpoint);
                        assert (rc == 0);
                    }
                    zstr_free (&endpoint);
                }
                else
                if (streq (command, "STOP"))
                    stopped = true;
                else
                    assert (0); //  Cannot happen, so die

                //  Signal to caller that we processed the command
                zsocket_signal (command_pipe);
            }
            else
                assert (0);     //  Cannot happen, so die
        }
        else
            break;              //  Interrupted
    }
    zpoller_destroy (&poller);
}
예제 #5
0
파일: zauth_v2.c 프로젝트: hisitepu/czmq
static int
s_agent_handle_pipe (agent_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    char *command = zmsg_popstr (request);
    if (!command)
        return -1;                  //  Interrupted

    if (streq (command, "ALLOW")) {
        char *address = zmsg_popstr (request);
        zhash_insert (self->whitelist, address, "OK");
        zstr_free (&address);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "DENY")) {
        char *address = zmsg_popstr (request);
        zhash_insert (self->blacklist, address, "OK");
        zstr_free (&address);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "PLAIN")) {
        //  For now we don't do anything with domains
        char *domain = zmsg_popstr (request);
        zstr_free (&domain);
        //  Get password file and load into zhash table
        //  If the file doesn't exist we'll get an empty table
        char *filename = zmsg_popstr (request);
        zhash_destroy (&self->passwords);
        self->passwords = zhash_new ();
        zhash_load (self->passwords, filename);
        zstr_free (&filename);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "CURVE")) {
        char *domain = zmsg_popstr (request);
        //  For now we don't do anything with domains
        zstr_free (&domain);
        //  If location is CURVE_ALLOW_ANY, allow all clients. Otherwise
        //  treat location as a directory that holds the certificates.
        char *location = zmsg_popstr (request);
        if (streq (location, CURVE_ALLOW_ANY))
            self->allow_any = true;
        else {
            zcertstore_destroy (&self->certstore);
            self->certstore = zcertstore_new (location);
            self->allow_any = false;
        }
        zstr_free (&location);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "GSSAPI")) {
        char *domain = zmsg_popstr (request);
        //  For now we don't do anything with domains
        zstr_free (&domain);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "VERBOSE")) {
        char *verbose = zmsg_popstr (request);
        self->verbose = *verbose == '1';
        zstr_free (&verbose);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "TERMINATE")) {
        self->terminated = true;
        zsocket_signal (self->pipe);
    }
    else {
        zsys_error ("invalid command from API: %s\n", command);
        assert (false);
    }
    zstr_free (&command);
    zmsg_destroy (&request);
    return 0;
}
예제 #6
0
파일: zyre_node.c 프로젝트: mjhowell/zyre
static int
zyre_node_recv_api (zyre_node_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    char *command = zmsg_popstr (request);
    if (!command)
        return -1;                  //  Interrupted

    if (streq (command, "SET")) {
        char *name = zmsg_popstr (request);
        char *value = zmsg_popstr (request);
        zhash_update (self->headers, name, value);
        zstr_free (&name);
        zstr_free (&value);
    }
    else
    if (streq (command, "VERBOSE")) {
        self->verbose = true;
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "START")) {
        zyre_node_start (self);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "STOP")) {
        zyre_node_stop (self);
        zsocket_signal (self->pipe);
    }
    else
    if (streq (command, "WHISPER")) {
        //  Get peer to send message to
        char *identity = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, identity);
        
        //  Send frame on out to peer's mailbox, drop message
        //  if peer doesn't exist (may have been destroyed)
        if (peer) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_WHISPER);
            zre_msg_set_content (msg, &request);
            zyre_peer_send (peer, &msg);
        }
        zstr_free (&identity);
    }
    else
    if (streq (command, "SHOUT")) {
        //  Get group to send message to
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->peer_groups, name);
        if (group) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_SHOUT);
            zre_msg_set_group (msg, name);
            zre_msg_set_content (msg, &request);
            zyre_group_send (group, &msg);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "JOIN")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->own_groups, name);
        if (!group) {
            //  Only send if we're not already in group
            group = zyre_group_new (name, self->own_groups);
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_JOIN);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            zhash_foreach (self->peers, zyre_node_send_peer, msg);
            zre_msg_destroy (&msg);
            zyre_log_info (self->log, ZRE_LOG_MSG_EVENT_JOIN, NULL, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "LEAVE")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->own_groups, name);
        if (group) {
            //  Only send if we are actually in group
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_LEAVE);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            zhash_foreach (self->peers, zyre_node_send_peer, msg);
            zre_msg_destroy (&msg);
            zhash_delete (self->own_groups, name);
            zyre_log_info (self->log, ZRE_LOG_MSG_EVENT_LEAVE, NULL, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "TERMINATE")) {
        self->terminated = true;
        zsocket_signal (self->pipe);
    }
    else {
        printf ("E: invalid command '%s'\n", command);
        assert (false);
    }
    zstr_free (&command);
    zmsg_destroy (&request);
    return 0;
}