Ejemplo n.º 1
0
static int
zyre_node_start (zyre_node_t *self)
{
    //  If application didn't bind explicitly, we grab an ephemeral port
    //  on all available network interfaces. This is orthogonal to
    //  beaconing, since we can connect to other peers and they will
    //  gossip our endpoint to others.
    if (!self->bound) {
        self->port = zsock_bind (self->inbox, "tcp://*:*");
        if (self->port < 0)
            return 1;           //  Could not get new port to bind to?
        self->bound = true;
    }
    //  Start UDP beaconing, if the application didn't disable it
    if (self->beacon_port) {
        assert (!self->beacon);
        self->beacon = zbeacon_new (NULL, self->beacon_port);
        if (!self->beacon)
            return 1;               //  Not possible to start beacon

        if (self->interval)
            zbeacon_set_interval (self->beacon, self->interval);
        zpoller_add (self->poller, zbeacon_socket (self->beacon));

        //  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);
        zbeacon_noecho (self->beacon);
        zbeacon_publish (self->beacon, (byte *) &beacon, sizeof (beacon_t));
        zbeacon_subscribe (self->beacon, (byte *) "ZRE", 3);

        //  Our own host endpoint is provided by the beacon
        assert (!self->endpoint);
        self->endpoint = zsys_sprintf ("tcp://%s:%d",
            zbeacon_hostname (self->beacon), self->port);
    }
    else
    if (!self->endpoint) {
        char *hostname = zsys_hostname ();
        self->endpoint = zsys_sprintf ("tcp://%s:%d", hostname, self->port);
        zstr_free (&hostname);
    }
    //  Start polling on inbox
    zpoller_add (self->poller, self->inbox);
    return 0;
}
Ejemplo n.º 2
0
static void
s_bind_proxy_sockets (zactor_t *proxy, char **frontend, char **backend)
{
    if (*frontend)
        zstr_free (frontend);
    if (*backend)
        zstr_free (backend);
    *frontend = zsys_sprintf (LOCALENDPOINT, s_get_available_port ());
    *backend = zsys_sprintf (LOCALENDPOINT, s_get_available_port ());
    zstr_sendx (proxy, "FRONTEND", "PULL", *frontend, NULL);
    zsock_wait (proxy);
    zstr_sendx (proxy, "BACKEND", "PUSH", *backend, NULL);
    zsock_wait (proxy);
}
Ejemplo n.º 3
0
int
hydra_post_save (hydra_post_t *self, const char *filename)
{
    assert (self);
    assert (filename);

    //  Creeate subdirectories if necessary
    zsys_dir_create ("posts");
    zsys_dir_create ("posts/blobs");

    //  If post content hasn't yet been serialised, write it to disk in the
    //  blobs directory and set the location property to point to it.
    if (self->content) {
        assert (!self->location);
        self->location = zsys_sprintf ("posts/blobs/%s", self->digest);
        FILE *output = fopen (self->location, "wb");
        zchunk_write (self->content, output);
        zchunk_destroy (&self->content);
        fclose (output);
    }
    zconfig_t *root = zconfig_new ("root", NULL);
    zconfig_put (root, "/post/ident", hydra_post_ident (self));
    zconfig_put (root, "/post/subject", self->subject);
    zconfig_put (root, "/post/timestamp", self->timestamp);
    zconfig_put (root, "/post/parent-id", self->parent_id);
    zconfig_put (root, "/post/mime-type", self->mime_type);
    zconfig_put (root, "/post/digest", self->digest);
    zconfig_put (root, "/post/location", self->location);
    zconfig_putf (root, "/post/content-size", "%ld", self->content_size);
    zconfig_savef (root, "posts/%s", filename);
    zconfig_destroy (&root);
    return 0;
}
Ejemplo n.º 4
0
JNIEXPORT jstring JNICALL
Java_org_zeromq_czmq_Zsys__1_1sprintf (JNIEnv *env, jclass c, jstring format)
{
    char *format_ = (char *) (*env)->GetStringUTFChars (env, format, NULL);
    char *sprintf_ = (char *) zsys_sprintf (format_);
    jstring return_string_ = (*env)->NewStringUTF (env, sprintf_);
    (*env)->ReleaseStringUTFChars (env, format, format_);
    return return_string_;
}
Ejemplo n.º 5
0
const char *
hydra_post_ident (hydra_post_t *self)
{
    assert (self);
    zdigest_t *digest = zdigest_new ();
    if (digest) {
        char *digest_text = zsys_sprintf ("%s:%s:%s:%s:%s",
            self->subject, self->timestamp, self->parent_id,
            self->mime_type? self->mime_type: "", self->digest);
        zdigest_update (digest, (byte *) digest_text, strlen (digest_text));
        assert (strlen (zdigest_string (digest)) == ID_SIZE);
        strcpy (self->ident, zdigest_string (digest));
        zstr_free (&digest_text);
        zdigest_destroy (&digest);
    }
    return self->ident;
}
Ejemplo n.º 6
0
static void
s_self_start (self_t *self)
{
    assert (!self->sink);
    char *endpoint = zsys_sprintf ("inproc://zmonitor-%p", self->monitored);
    int rc;
#if defined (ZMQ_EVENT_ALL)
    rc = zmq_socket_monitor (self->monitored, endpoint, self->events);
    assert (rc == 0);
#endif
    self->sink = zsock_new (ZMQ_PAIR);
    assert (self->sink);
    rc = zsock_connect (self->sink, "%s", endpoint);
    assert (rc == 0);
    zpoller_add (self->poller, self->sink);
    free (endpoint);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
void
zconfig_test (bool verbose)
{
    printf (" * zconfig: ");

    //  @selftest

    const char *SELFTEST_DIR_RW = "src/selftest-rw";

    const char *testbasedir  = ".test_zconfig";
    const char *testfile = "test.cfg";
    char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
    char *filepath = NULL;      // pathname to testfile in a test, in dirpath

    basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
    assert (basedirpath);
    filepath = zsys_sprintf ("%s/%s", basedirpath, testfile);
    assert (filepath);

    // Make sure old aborted tests do not hinder us
    zdir_t *dir = zdir_new (basedirpath, NULL);
    if (dir) {
        zdir_remove (dir, true);
        zdir_destroy (&dir);
    }
    zsys_file_delete (filepath);
    zsys_dir_delete  (basedirpath);

    //  Create temporary directory for test files
    zsys_dir_create (basedirpath);

    zconfig_t *root = zconfig_new ("root", NULL);
    assert (root);
    zconfig_t *section, *item;

    section = zconfig_new ("headers", root);
    assert (section);
    item = zconfig_new ("email", section);
    assert (item);
    zconfig_set_value (item, "*****@*****.**");
    item = zconfig_new ("name", section);
    assert (item);
    zconfig_set_value (item, "Justin Kayce");
    zconfig_putf (root, "/curve/secret-key", "%s", "Top Secret");
    zconfig_set_comment (root, "   CURVE certificate");
    zconfig_set_comment (root, "   -----------------");
    assert (zconfig_comments (root));
    zconfig_save (root, filepath);
    zconfig_destroy (&root);
    root = zconfig_load (filepath);
    if (verbose)
        zconfig_save (root, "-");
    assert (streq (zconfig_filename (root), filepath));

    char *email = zconfig_get (root, "/headers/email", NULL);
    assert (email);
    assert (streq (email, "*****@*****.**"));
    char *passwd = zconfig_get (root, "/curve/secret-key", NULL);
    assert (passwd);
    assert (streq (passwd, "Top Secret"));

    zconfig_savef (root, "%s/%s", basedirpath, testfile);
    assert (!zconfig_has_changed (root));
    int rc = zconfig_reload (&root);
    assert (rc == 0);
    assert (!zconfig_has_changed (root));
    zconfig_destroy (&root);

    //  Test chunk load/save
    root = zconfig_new ("root", NULL);
    assert (root);
    section = zconfig_new ("section", root);
    assert (section);
    item = zconfig_new ("value", section);
    assert (item);
    zconfig_set_value (item, "somevalue");
    zconfig_t *search = zconfig_locate (root, "section/value");
    assert (search == item);
    zchunk_t *chunk = zconfig_chunk_save (root);
    assert (strlen ((char *) zchunk_data (chunk)) == 32);
    char *string = zconfig_str_save (root);
    assert (string);
    assert (streq (string, (char *) zchunk_data (chunk)));
    freen (string);
    assert (chunk);
    zconfig_destroy (&root);

    root = zconfig_chunk_load (chunk);
    assert (root);
    char *value = zconfig_get (root, "/section/value", NULL);
    assert (value);
    assert (streq (value, "somevalue"));

    //  Test config can't be saved to a file in a path that doesn't
    //  exist or isn't writable
    rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", basedirpath, testfile);
    assert (rc == -1);

    zconfig_destroy (&root);
    zchunk_destroy (&chunk);

    //  Test subtree removal
	{
		zconfig_t *root = zconfig_str_load (
			"context\n"
			"    iothreads = 1\n"
			"    verbose = 1      #   Ask for a trace\n"
			"main\n"
			"    type = zqueue    #  ZMQ_DEVICE type\n"
			"    frontend\n"
			"        option\n"
			"            hwm = 1000\n"
			"            swap = 25000000     #  25MB\n"
			"        bind = 'inproc://addr1'\n"
			"        bind = 'ipc://addr2'\n"
			"    backend\n"
			"        bind = inproc://addr3\n"
		);

        zconfig_t *to_delete = zconfig_locate (root, "main/frontend");
        assert (to_delete);

        zconfig_remove (to_delete);

        char *value = zconfig_get (root, "/main/type", NULL);
        assert (value);
        assert (streq (value, "zqueue"));

        value = zconfig_get (root, "/main/backend/bind", NULL);
        assert (value);
        assert (streq (value, "inproc://addr3"));

        value = zconfig_get (root, "/main/frontend", NULL);
        assert (value);

        value = zconfig_get (root, "/main/frontend/option", NULL);
        assert (value == NULL);

        value = zconfig_get (root, "/main/frontend/option/swap", NULL);
        assert (value == NULL);

        zconfig_destroy (&root);
	}

    // Test str_load
    zconfig_t *config = zconfig_str_load (
        "malamute\n"
        "    endpoint = ipc://@/malamute\n"
        "    producer = STREAM\n"
        "    consumer\n"
        "        STREAM2 = .*\n"
        "        STREAM3 = HAM\n"
        "server\n"
        "    verbose = true\n"
        );
    assert (config);
    assert (streq (zconfig_get (config, "malamute/endpoint", NULL), "ipc://@/malamute"));
    assert (streq (zconfig_get (config, "malamute/producer", NULL), "STREAM"));
    assert (zconfig_locate (config, "malamute/consumer"));

    zconfig_t *c = zconfig_child (zconfig_locate (config, "malamute/consumer"));
    assert (c);
    assert (streq (zconfig_name (c), "STREAM2"));
    assert (streq (zconfig_value (c), ".*"));

    c = zconfig_next (c);
    assert (c);
    assert (streq (zconfig_name (c), "STREAM3"));
    assert (streq (zconfig_value (c), "HAM"));

    c = zconfig_next (c);
    assert (!c);

    assert (streq (zconfig_get (config, "server/verbose", NULL), "true"));

    zconfig_destroy (&config);

    //  Delete all test files
    dir = zdir_new (basedirpath, NULL);
    assert (dir);
    zdir_remove (dir, true);
    zdir_destroy (&dir);

    zstr_free (&basedirpath);
    zstr_free (&filepath);

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif
    //  @end

    printf ("OK\n");
}
Ejemplo n.º 9
0
///
//  Format a string using printf formatting, returning a freshly allocated
//  buffer. If there was insufficient memory, returns NULL. Free the returned
//  string using zstr_free().
const QString QmlZsysAttached::sprintf (const QString &format) {
    return QString (zsys_sprintf (format.toUtf8().data()));
};
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
bool
serverCreateProcess (
    ServerInfo *self,
    char *executableName
) {
    MySQLInfo *sqlInfo = &self->workersInfo[0].sqlInfo;
    RedisInfo *redisInfo = &self->workersInfo[0].redisInfo;
    char *globalServerIp = self->workersInfo[0].globalServerIp;
    int globalServerPort = self->workersInfo[0].globalServerPort;

#ifdef WIN32
    executableName = zsys_sprintf("%s.exe", executableName);
#endif

    char *commandLine = zsys_sprintf("%s %d %s %d",
                                     executableName,
                                     self->routerInfo.routerId,
                                     self->routerInfo.ip,
                                     self->routerInfo.port
                                    );

    char *lastCommandLine;
    lastCommandLine = zsys_sprintf("%s %d %s %d %s %s %s %s %s %d %d %s",
                                   commandLine,
                                   self->routerInfo.workersCount,
                                   globalServerIp,
                                   globalServerPort,
                                   sqlInfo->hostname, sqlInfo->user, sqlInfo->password, sqlInfo->database,
                                   redisInfo->hostname, redisInfo->port,
                                   self->serverType,
                                   self->output
                                  );

    zstr_free(&commandLine);
    commandLine = lastCommandLine;

    info("CommandLine : %s", commandLine);

#ifdef WIN32
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};
    if (!CreateProcess (executableName, commandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
        error("Cannot launch Zone Server executable : %s.", executableName);
        char *errorReason;
        FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &errorReason, 0, NULL
                      );
        error("Error reason : %s", errorReason);
        return false;
    }
#else
    char **argv = strSplit (commandLine, ' ');
    if (fork () == 0) {
        if (execv (executableName, (char * const *) argv) == -1) {
            error("Cannot launch Zone Server executable : %s.", executableName);
            return false;
        }
    }
    free(argv);
#endif

    zstr_free(&commandLine);
    return true;
}
Ejemplo n.º 12
0
void
zcertstore_test (bool verbose)
{
    printf (" * zcertstore: ");
    if (verbose)
        printf ("\n");

    //  @selftest

    const char *SELFTEST_DIR_RW = "src/selftest-rw";

    const char *testbasedir  = ".test_zcertstore";
    const char *testfile = "mycert.txt";
    char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
    char *filepath = NULL;      // pathname to testfile in a test, in dirpath

    basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
    assert (basedirpath);
    filepath = zsys_sprintf ("%s/%s", basedirpath, testfile);
    assert (filepath);

    // Make sure old aborted tests do not hinder us
    zdir_t *dir = zdir_new (basedirpath, NULL);
    if (dir) {
        zdir_remove (dir, true);
        zdir_destroy (&dir);
    }
    zsys_file_delete (filepath);
    zsys_dir_delete  (basedirpath);

    //  Create temporary directory for test files
    zsys_dir_create (basedirpath);

    //  Load certificate store from disk; it will be empty
    zcertstore_t *certstore = zcertstore_new (basedirpath);
    assert (certstore);

    //  Create a single new certificate and save to disk
    zcert_t *cert = zcert_new ();
    assert (cert);
    char *client_key = strdup (zcert_public_txt (cert));
    assert (client_key);
    zcert_set_meta (cert, "name", "John Doe");
    zcert_save (cert, filepath);
    zcert_destroy (&cert);

    //  Check that certificate store refreshes as expected
    cert = zcertstore_lookup (certstore, client_key);
    assert (cert);
    assert (streq (zcert_meta (cert, "name"), "John Doe"));

#ifdef CZMQ_BUILD_DRAFT_API
    //  DRAFT-API: Security
    // Iterate through certs
    zlistx_t *certs = zcertstore_certs(certstore);
    cert = (zcert_t *) zlistx_first(certs);
    int cert_count = 0;
    while (cert) {
        assert (streq (zcert_meta (cert, "name"), "John Doe"));
        cert = (zcert_t *) zlistx_next(certs);
        cert_count++;
    }
    assert(cert_count==1);
    zlistx_destroy(&certs);
#endif

    //  Test custom loader
    test_loader_state *state = (test_loader_state *) zmalloc (sizeof (test_loader_state));
    state->index = 0;
    zcertstore_set_loader (certstore, s_test_loader, s_test_destructor, (void *)state);
#if (ZMQ_VERSION_MAJOR >= 4)
    cert = zcertstore_lookup (certstore, client_key);
    assert (cert == NULL);
    cert = zcertstore_lookup (certstore, "abcdefghijklmnopqrstuvwxyzabcdefghijklmn");
    assert (cert);
#endif

    freen (client_key);

    if (verbose)
        zcertstore_print (certstore);
    zcertstore_destroy (&certstore);

    //  Delete all test files
    dir = zdir_new (basedirpath, NULL);
    assert (dir);
    zdir_remove (dir, true);
    zdir_destroy (&dir);

    zstr_free (&basedirpath);
    zstr_free (&filepath);

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif
    //  @end
    printf ("OK\n");
}
Ejemplo n.º 13
0
bool
GlobalServer_start (
    GlobalServer *self
) {
    #ifdef WIN32
        SetConsoleTitle ("GlobalServer");
    #endif // WIN32

    special ("======================");
    special ("=== Global server ====");
    special ("======================");

    GlobalServerStartupInfo *info = &self->info;

    zpoller_t *poller;
    bool isRunning = true;
    ServerStartupInfo serverInfo;

    // ===================================
    //     Initialize CLI connection
    // ===================================
    // CLI should communicates through BSD sockets
    zsock_set_router_raw (self->cliConnection, true);

    if (zsock_bind (self->cliConnection, GLOBAL_SERVER_CLI_ENDPOINT, info->ip, info->cliPort) == -1) {
        error ("Failed to bind CLI port.");
        return false;
    }
    info ("CLI connection binded on port %s.", zsys_sprintf (GLOBAL_SERVER_CLI_ENDPOINT, info->ip, info->cliPort));


    // ===================================
    //     Initialize Zones connection
    // ===================================
    if ((info->zonesPort = zsock_bind (self->zonesConnection, GLOBAL_SERVER_ZONES_ENDPOINT, info->ip)) == -1) {
        error ("Failed to bind zones port.");
        return false;
    }
    info ("Zones connection binded on port %s.", zsys_sprintf (GLOBAL_SERVER_ZONES_ENDPOINT, info->ip, info->zonesPort));

    // ===================================
    //     Initialize 1 Barrack Server
    // ===================================
    if (!(ServerFactory_initServerInfo (&serverInfo,
        SERVER_TYPE_BARRACK,
        BARRACK_SERVER_ROUTER_ID,
        info->barrackServerIp,
        info->barrackServerPortCount, info->barrackServerPort,
        info->zoneWorkersCount,
        info->ip, info->cliPort,
        info->sqlInfo.hostname, info->sqlInfo.login, info->sqlInfo.password, info->sqlInfo.database,
        info->redisInfo.hostname, info->redisInfo.port)
    )) {
        error ("[Barrack] Cannot create a new ServerInfo.");
        return false;
    }

    if (!(Server_createProcess (&serverInfo, ZONE_SERVER_EXECUTABLE_NAME))) {
        error ("[Barrack] Can't launch a new Server process.");
        return false;
    }

    // ===================================
    //     Initialize N Social Server
    // ===================================
    for (uint16_t routerId = 0; routerId < info->socialServersCount; routerId++) {
        ServerFactory_initServerInfo (&serverInfo,
            SERVER_TYPE_SOCIAL,
            SOCIAL_SERVER_ROUTER_ID - routerId,
            info->socialServersIp[routerId],
            1, &info->socialServersPorts[routerId], // Only 1 port for each social server
            info->socialWorkersCount,
            info->ip, info->cliPort,
            info->sqlInfo.hostname, info->sqlInfo.login, info->sqlInfo.password, info->sqlInfo.database,
            info->redisInfo.hostname, info->redisInfo.port
        );

        if (!(Server_createProcess (&serverInfo, ZONE_SERVER_EXECUTABLE_NAME))) {
            error ("[routerId=%d] Can't launch a new Server process.", routerId);
            return false;
        }
    }

    // ===================================
    //     Initialize N Zone Server
    // ===================================
    for (uint16_t routerId = 0; routerId < info->zoneServersCount; routerId++) {
        ServerFactory_initServerInfo (&serverInfo,
            SERVER_TYPE_ZONE,
            routerId,
            info->zoneServersIp[routerId],
            1, &info->zoneServersPorts[routerId], // Only 1 port for each Zone server
            info->zoneWorkersCount,
            info->ip, info->cliPort,
            info->sqlInfo.hostname, info->sqlInfo.login, info->sqlInfo.password, info->sqlInfo.database,
            info->redisInfo.hostname, info->redisInfo.port
        );

        if (!(Server_createProcess (&serverInfo, ZONE_SERVER_EXECUTABLE_NAME))) {
            error ("[routerId=%d] Can't launch a new Server process.", routerId);
            return false;
        }
    }

    // Define a poller with the zones and the CLI sockets
    if (!(poller = zpoller_new (self->cliConnection, self->zonesConnection, NULL))) {
        error ("Global server cannot create a poller.");
        return false;
    }

    // Listens to requests
    info ("GlobalServer is ready and running.");

    while (isRunning) {
        zsock_t *actor = zpoller_wait (poller, -1);
        typedef int (*GlobalServerRequestHandler) (GlobalServer *self, zsock_t *actor);
        GlobalServerRequestHandler handler;

        // Get the correct handler based on the actor
        if (actor == self->zonesConnection) {
            handler = GlobalServer_handleZonesRequest;
        } else if (actor == self->cliConnection) {
            handler = GlobalServer_handleCliRequest;
        }
        else {
            warning ("An unknown actor talked to the Global Server. Maybe SIGINT signal ?");
            break;
        }

        switch (handler (self, actor)) {
            case -1: // ERROR
                error ("Global Server encountered an error when handling a request.");
            case -2: // Connection stopped
                isRunning = false;
            break;

            case 0: // OK
            break;
        }
    }

    return true;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
void
zfile_test (bool verbose)
{
    printf (" * zfile: ");

    //  @selftest

    const char *SELFTEST_DIR_RW = "src/selftest-rw";

    const char *testbasedir  = "this";
    const char *testsubdir  = "is/a/test";
    const char *testfile = "bilbo";
    const char *testlink = "bilbo.ln";
    char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
    char *dirpath = NULL;       // subdir in a test, under basedirpath
    char *filepath = NULL;      // pathname to testfile in a test, in dirpath
    char *linkpath = NULL;      // pathname to testlink in a test, in dirpath

    basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
    assert (basedirpath);
    dirpath = zsys_sprintf ("%s/%s", basedirpath, testsubdir);
    assert (dirpath);
    filepath = zsys_sprintf ("%s/%s", dirpath, testfile);
    assert (filepath);
    linkpath = zsys_sprintf ("%s/%s", dirpath, testlink);
    assert (linkpath);

    // This subtest is specifically for NULL as current directory, so
    // no SELFTEST_DIR_RW here; testfile should have no slashes inside.
    // Normally tests clean up in zfile_destroy(), but if a selftest run
    // dies e.g. on assert(), workspace remains dirty. Better clean it up.
    if (zfile_exists (testfile) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove ./%s that should not have been here", testfile);
        zfile_delete (testfile);
    }
    zfile_t *file = zfile_new (NULL, testfile);
    assert (file);
    assert (streq (zfile_filename (file, "."), testfile));
    assert (zfile_is_readable (file) == false);
    zfile_destroy (&file);

    //  Create a test file in some random subdirectory
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Creating new zfile %s",
            zclock_time(), filepath );

    if (zfile_exists (filepath) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath);
        zfile_delete (filepath);
    }

    file = zfile_new (dirpath, testfile);
    assert (file);
    int rc = zfile_output (file);
    assert (rc == 0);
    zchunk_t *chunk = zchunk_new (NULL, 100);
    assert (chunk);
    zchunk_fill (chunk, 0, 100);

    //  Write 100 bytes at position 1,000,000 in the file
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Writing 100 bytes at position 1,000,000 in the file",
            zclock_time() );
    rc = zfile_write (file, chunk, 1000000);
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Wrote 100 bytes at position 1,000,000 in the file, result code %d",
            zclock_time(), rc );
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_is_readable (file));
    assert (zfile_cursize (file) == 1000100);
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Testing if file is NOT stable (is younger than 1 sec)",
            zclock_time() );
    assert (!zfile_is_stable (file));
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Passed the lag-dependent tests",
            zclock_time() );
    assert (zfile_digest (file));

    //  Now truncate file from outside
    int handle = open (filepath, O_WRONLY | O_TRUNC | O_BINARY, 0);
    assert (handle >= 0);
    rc = write (handle, "Hello, World\n", 13);
    assert (rc == 13);
    close (handle);
    assert (zfile_has_changed (file));
#ifdef CZMQ_BUILD_DRAFT_API
    zclock_sleep ((int)zsys_file_stable_age_msec() + 50);
#else
    zclock_sleep (5050);
#endif
    assert (zfile_has_changed (file));

    assert (!zfile_is_stable (file));
    zfile_restat (file);
    assert (zfile_is_stable (file));
    assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54"));

    //  Check we can read from file
    rc = zfile_input (file);
    assert (rc == 0);
    chunk = zfile_read (file, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_close (file);

    //  Check we can read lines from file
    rc = zfile_input (file);
    assert (rc == 0);
    const char *line = zfile_readln (file);
    assert (streq (line, "Hello, World"));
    line = zfile_readln (file);
    assert (line == NULL);
    zfile_close (file);

    //  Try some fun with symbolic links
    zfile_t *link = zfile_new (dirpath, testlink);
    assert (link);
    rc = zfile_output (link);
    assert (rc == 0);
    fprintf (zfile_handle (link), "%s\n", filepath);
    zfile_destroy (&link);

    link = zfile_new (dirpath, testlink);
    assert (link);
    rc = zfile_input (link);
    assert (rc == 0);
    chunk = zfile_read (link, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_destroy (&link);

    //  Remove file and directory
    zdir_t *dir = zdir_new (basedirpath, NULL);
    assert (dir);
    assert (zdir_cursize (dir) == 26);
    zdir_remove (dir, true);
    assert (zdir_cursize (dir) == 0);
    zdir_destroy (&dir);

    //  Check we can no longer read from file
    assert (zfile_is_readable (file));
    zfile_restat (file);
    assert (!zfile_is_readable (file));
    rc = zfile_input (file);
    assert (rc == -1);
    zfile_destroy (&file);

    // This set of tests is done, free the strings for reuse
    zstr_free (&basedirpath);
    zstr_free (&dirpath);
    zstr_free (&filepath);
    zstr_free (&linkpath);

    const char *eof_checkfile = "eof_checkfile";
    filepath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, eof_checkfile);
    assert (filepath);

    if (zfile_exists (filepath) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath);
        zfile_delete (filepath);
    }
    zstr_free (&filepath);

    file = zfile_new (SELFTEST_DIR_RW, eof_checkfile);
    assert (file);

    //  1. Write something first
    rc = zfile_output (file);
    assert (rc == 0);
    chunk = zchunk_new ("123456789", 9);
    assert (chunk);

    rc = zfile_write (file, chunk, 0);
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_cursize (file) == 9);

    // 2. Read the written something
    rc = zfile_input (file);
    assert (rc != -1);
    // try to read more bytes than there is in the file
    chunk = zfile_read (file, 1000, 0);
    assert (zfile_eof(file));
    assert (zchunk_streq (chunk, "123456789"));
    zchunk_destroy (&chunk);

    // reading is ok
    chunk = zfile_read (file, 5, 0);
    assert (!zfile_eof(file));
    assert (zchunk_streq (chunk, "12345"));
    zchunk_destroy (&chunk);

    // read from non zero offset until the end
    chunk = zfile_read (file, 5, 5);
    assert (zfile_eof(file));
    assert (zchunk_streq (chunk, "6789"));
    zchunk_destroy (&chunk);
    zfile_remove (file);
    zfile_close (file);
    zfile_destroy (&file);

#ifdef CZMQ_BUILD_DRAFT_API
    zfile_t *tempfile = zfile_tmp ();
    assert (tempfile);
    assert (zfile_filename (tempfile, NULL));
    assert (zsys_file_exists (zfile_filename (tempfile, NULL)));
    zchunk_t *tchunk = zchunk_new ("HELLO", 6);
    assert (zfile_write (tempfile, tchunk, 0) == 0);
    zchunk_destroy (&tchunk);

    char *filename = strdup (zfile_filename (tempfile, NULL));
    zfile_destroy (&tempfile);
    assert (!zsys_file_exists (filename));
    zstr_free (&filename);
#endif // CZMQ_BUILD_DRAFT_API

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif

    //  @end

    printf ("OK\n");
}
Ejemplo n.º 16
0
Archivo: zsys.c Proyecto: wysman/czmq
void
zsys_test (bool verbose)
{
    printf (" * zsys: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    zsys_catch_interrupts ();

    //  Check capabilities without using the return value
    int rc = zsys_has_curve ();

    if (verbose) {
        char *hostname = zsys_hostname ();
        zsys_info ("host name is %s", hostname);
        free (hostname);
        zsys_info ("system limit is %zd ZeroMQ sockets", zsys_socket_limit ());
    }
    zsys_set_io_threads (1);
    zsys_set_max_sockets (0);
    zsys_set_linger (0);
    zsys_set_sndhwm (1000);
    zsys_set_rcvhwm (1000);
    zsys_set_pipehwm (2500);
    assert (zsys_pipehwm () == 2500);

    zsys_set_ipv6 (0);

    rc = zsys_file_delete ("nosuchfile");
    assert (rc == -1);

    bool rc_bool = zsys_file_exists ("nosuchfile");
    assert (rc_bool != true);

    rc = (int) zsys_file_size ("nosuchfile");
    assert (rc == -1);

    time_t when = zsys_file_modified (".");
    assert (when > 0);

    mode_t mode = zsys_file_mode (".");
    assert (S_ISDIR (mode));
    assert (mode & S_IRUSR);
    assert (mode & S_IWUSR);

    zsys_file_mode_private ();
    rc = zsys_dir_create ("%s/%s", ".", ".testsys/subdir");
    assert (rc == 0);
    when = zsys_file_modified ("./.testsys/subdir");
    assert (when > 0);
    assert (!zsys_file_stable ("./.testsys/subdir"));
    rc = zsys_dir_delete ("%s/%s", ".", ".testsys/subdir");
    assert (rc == 0);
    rc = zsys_dir_delete ("%s/%s", ".", ".testsys");
    assert (rc == 0);
    zsys_file_mode_default ();

    int major, minor, patch;
    zsys_version (&major, &minor, &patch);
    assert (major == CZMQ_VERSION_MAJOR);
    assert (minor == CZMQ_VERSION_MINOR);
    assert (patch == CZMQ_VERSION_PATCH);

    char *string = zsys_sprintf ("%s %02x", "Hello", 16);
    assert (streq (string, "Hello 10"));
    free (string);

    char *str64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,.";
    int num10 = 1234567890;
    string = zsys_sprintf ("%s%s%s%s%d", str64, str64, str64, str64, num10);
    assert (strlen (string) == (4 * 64 + 10));
    free (string);

    //  Test logging system
    zsys_set_logident ("czmq_selftest");
    zsys_set_logsender ("inproc://logging");
    void *logger = zsys_socket (ZMQ_SUB, NULL, 0);
    assert (logger);
    rc = zsocket_connect (logger, "inproc://logging");
    assert (rc == 0);
    rc = zmq_setsockopt (logger, ZMQ_SUBSCRIBE, "", 0);
    assert (rc == 0);

    if (verbose) {
        zsys_error ("This is an %s message", "error");
        zsys_warning ("This is a %s message", "warning");
        zsys_notice ("This is a %s message", "notice");
        zsys_info ("This is a %s message", "info");
        zsys_debug ("This is a %s message", "debug");
        zsys_set_logident ("hello, world");
        zsys_info ("This is a %s message", "info");
        zsys_debug ("This is a %s message", "debug");

        //  Check that logsender functionality is working
        char *received = zstr_recv (logger);
        assert (received);
        zstr_free (&received);
    }
    zsys_close (logger, NULL, 0);
    //  @end

    printf ("OK\n");
}
Ejemplo n.º 17
0
int main (int argc, char **argv)
{
    if (argc <= 1) {
        info("Please launch global_server instead of zone_server. (argc=%d)", argc);
        exit (0);
    }

    ZoneServer *zoneServer = NULL;
    BarrackServer *barrackServer = NULL;
    SocialServer *socialServer = NULL;

    // === Crash handler ===
#ifdef WIN32
    SetUnhandledExceptionFilter (crashHandler);
#else
    struct sigaction sa = {};
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = crashHandler;
    sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGABRT, &sa, NULL);
#endif

    // === Read the command line arguments ===
    RouterId_t routerId = atoi(*++argv);
    char *routerIp = *++argv;
    int port = atoi(*++argv);
    uint16_t workersCount = atoi(*++argv);
    char *globalServerIp = *++argv;
    int globalServerPort = atoi(*++argv);
    char *sqlHostname = *++argv;
    char *sqlUsername = *++argv;
    char *sqlPassword = *++argv;
    char *sqlDatabase = *++argv;
    char *redisHostname = *++argv;
    int redisPort = atoi(*++argv);
    ServerType serverType = atoi(*++argv);
    char *output = *++argv;

    // Set a custom output
    dbgSetCustomOutput(output);

    // For Windows, change the console title
#ifdef WIN32
    switch (serverType) {
    case SERVER_TYPE_BARRACK:
        SetConsoleTitle(zsys_sprintf("Barrack (%d)", routerId));
        break;

    case SERVER_TYPE_ZONE:
        SetConsoleTitle(zsys_sprintf("Zone (%d)", routerId));
        break;

    case SERVER_TYPE_SOCIAL:
        SetConsoleTitle(zsys_sprintf("Social (%d)", routerId));
        break;

    default :
        SetConsoleTitle(zsys_sprintf("UNKNOWN (%d)", routerId));
        break;
    }
#endif

    // === Build the Event Server ===
    EventServer *eventServer;
    EventServerInfo eventServerInfo;
    if (!(eventServerInfoInit(&eventServerInfo, routerId, workersCount, redisHostname, redisPort))) {
        error("Cannot initialize the event server.");
        return -1;
    }
    if (!(eventServer = eventServerNew(&eventServerInfo, serverType))) {
        error("Cannot create the event server.");
        return -1;
    }
    if ((zthread_new((zthread_detached_fn *) eventServerStart, eventServer)) != 0) {
        error("Cannot start the event server.");
        return -1;
    }

    // Specific server stuff
    DisconnectEventHandler disconnectHandler;
    switch (serverType) {
    case SERVER_TYPE_BARRACK:
        disconnectHandler = barrackEventServerOnDisconnect;
        break;

    case SERVER_TYPE_ZONE:
        disconnectHandler = zoneEventServerOnDisconnect;
        break;

    case SERVER_TYPE_SOCIAL:
        disconnectHandler = socialEventServerOnDisconnect;
        break;

    default :
        error("Unknown server type.");
        return 0;
        break;
    }

    // === Build the Server ===
    Server *server;
    if (!(server = serverFactoryCreateServer(
                       serverType,
                       routerId,
                       routerIp, port,
                       workersCount,
                       output,
                       globalServerIp, globalServerPort,
                       sqlHostname, sqlUsername, sqlPassword, sqlDatabase,
                       redisHostname, redisPort, disconnectHandler
                   ))) {
        error("Cannot create a Server.");
        return -1;
    }

    // Initialize the Server
    switch (serverType)
    {
    case SERVER_TYPE_BARRACK:
        // Initialize the Barrack Server
        if ((barrackServer = barrackServerNew(server))) {

            // Start the Barrack Server
            if (!barrackServerStart(barrackServer)) {
                error("Cannot start the BarrackServer properly.");
            }

            // Unload the Barrack Server properly
            barrackServerDestroy(&barrackServer);
        }
        else {
            error("Cannot initialize the BarrackServer properly.");
        }
        break;

    case SERVER_TYPE_ZONE:
        // Initialize the Zone Server
        if ((zoneServer = zoneServerNew(server))) {

            // Start the Zone Server
            if (!zoneServerStart(zoneServer)) {
                error("Cannot start the Zone Server properly.");
            }

            // Unload the Zone Server properly
            zoneServerDestroy(&zoneServer);
        }
        else {
            error("Cannot initialize the Zone Server properly.");
        }
        break;

    case SERVER_TYPE_SOCIAL:
        // Initialize the Social Server
        if ((socialServer = socialServerNew(server))) {

            // Start the Social Server
            if (!socialServerStart(socialServer)) {
                error("Cannot start the Social Server properly.");
            }

            // Unload the Social Server properly
            socialServerDestroy(&socialServer);
        }
        else {
            error("Cannot initialize the Social Server properly.");
        }
        break;

    default :
        error("Cannot start an unknown serverType.");
        break;
    }

    // Shutdown the CZMQ layer properly
    zsys_shutdown();

    // Close the custom debug file if necessary
    dbgClose();

    pause();

    return 0;
}
Ejemplo n.º 18
0
int main (int argc, char *argv [])
{
    puts (PRODUCT);
    puts (COPYRIGHT);
    puts (NOWARRANTY);

    int argn = 1;
    bool verbose = false;
    if (argn < argc && streq (argv [argn], "-h")) {
        puts ("syntax: hydrad [ directory ]");
        puts (" -- defaults to .hydra in current directory");
        exit (0);
    }
    if (argn < argc && streq (argv [argn], "-v")) {
        verbose = true;
        argn++;
    }
    //  By default, current node runs in .hydra directory; create this if
    //  it's missing (don't create directory passed as argument);
    char *workdir = ".hydra";
    if (argn < argc)
        workdir = argv [argn++];
    else
        zsys_dir_create (workdir);

    //  ----------------------------------------------------------------------
    //  This code eventually goes into a reusable hydra actor class

    //  Switch to working directory
    zsys_info ("hydrad: data store in %s directory", workdir);
    if (zsys_dir_change (workdir)) {
        zsys_error ("hydrad: cannot access %s: %s", workdir, strerror (errno));
        return 1;
    }
    //  Check we are the only process currently running here
    if (zsys_run_as ("hydrad.lock", NULL, NULL)) {
        zsys_error ("hydrad: cannot start process safely, exiting");
        return 1;
    }
    //  Get node identity from config file, or generate new identity
    zconfig_t *config = zconfig_load ("hydra.cfg");
    if (!config) {
        //  Set defaults for Hydra service
        config = zconfig_new ("root", NULL);
        zconfig_put (config, "/server/timeout", "5000");
        zconfig_put (config, "/server/background", "0");
        zconfig_put (config, "/server/verbose", "0");
    }
    char *identity = zconfig_resolve (config, "/hydra/identity", NULL);
    if (!identity) {
        zuuid_t *uuid = zuuid_new ();
        zconfig_put (config, "/hydra/identity", zuuid_str (uuid));
        zconfig_put (config, "/hydra/nickname", "Anonymous");
        zconfig_save (config, "hydra.cfg");
        zuuid_destroy (&uuid);
    }
    //  Create store structure, if necessary
    zsys_dir_create ("content");
    zsys_dir_create ("posts");
    
    //  Start server and bind to ephemeral TCP port. We can run many
    //  servers on the same box, for testing.
    zactor_t *server = zactor_new (hydra_server, NULL);
    if (verbose)
        zstr_send (server, "VERBOSE");

    //  Bind Hydra service to ephemeral port and get that port number
    char *command;
    int port_nbr;
    zsock_send (server, "ss", "CONFIGURE", "hydra.cfg");
    zsock_send (server, "ss", "BIND", "tcp://*:*");
    zsock_send (server, "s", "PORT");
    zsock_recv (server, "si", &command, &port_nbr);
    zsys_info ("hydrad: TCP server started on port=%d", port_nbr);
    assert (streq (command, "PORT"));
    free (command);

    //  We're going to use Zyre for discovery and presence, and our own
    //  Hydra protocol for content exchange
    zyre_t *zyre = zyre_new (NULL);
    if (verbose)
        zyre_set_verbose (zyre);

    char *hostname = zsys_hostname ();
    char *endpoint = zsys_sprintf ("tcp://%s:%d", hostname, port_nbr);
    zyre_set_header (zyre, "X-HYDRA", "%s", endpoint);
    zstr_free (&endpoint);
    zstr_free (&hostname);
    if (zyre_start (zyre)) {
        zsys_info ("hydrad: can't start Zyre discovery service");
        zactor_destroy (&server);
        zyre_destroy (&zyre);
        return 1;
    }
    //  When we get a new peer, handle it
    zpoller_t *poller = zpoller_new (zyre_socket (zyre), NULL);
    while (!zpoller_terminated (poller)) {
        void *which = zpoller_wait (poller, -1);
        if (which == zyre_socket (zyre)) {
            zyre_event_t *event = zyre_event_new (zyre);
            if (zyre_event_type (event) == ZYRE_EVENT_ENTER) {
                zsys_debug ("hydrad: new peer name=%s endpoint=%s",
                            zyre_event_name (event),
                            zyre_event_header (event, "X-HYDRA"));
                s_handle_peer (zyre_event_header (event, "X-HYDRA"), verbose);
            }
            zyre_event_destroy (&event);
        }
        else
            break;
    }
    zsys_info ("hydrad: shutting down...");
    zpoller_destroy (&poller);

    //  Shutdown all services
    zactor_destroy (&server);
    zyre_destroy (&zyre);
    zconfig_destroy (&config);
    return 0;
}
Ejemplo n.º 19
0
int
zsock_bind (zsock_t *self, const char *format, ...)
{
    assert (self);
    assert (zsock_is (self));

    //  Expand format to get full endpoint
    va_list argptr;
    va_start (argptr, format);
    char *endpoint = zsys_vprintf (format, argptr);
    va_end (argptr);
    int rc;
    
    //  If tcp:// endpoint, parse to get or make port number
    zrex_t *rex = zrex_new (NULL);
    if (zrex_eq (rex, endpoint, "^tcp://.*:(\\d+)$")) {
        assert (zrex_hits (rex) == 2);
        if (zmq_bind (self->handle, endpoint) == 0)
            rc = atoi (zrex_hit (rex, 1));
        else
            rc = -1;
    }
    else
    if (zrex_eq (rex, endpoint, "^(tcp://.*):([*!])(\\[(\\d+)?-(\\d+)?\\])?$")) {
        assert (zrex_hits (rex) == 6);
        const char *hostname, *opcode, *group, *first_str, *last_str;
        zrex_fetch (rex, &hostname, &opcode, &group, &first_str, &last_str, NULL);
        
        int first = *first_str? atoi (first_str): DYNAMIC_FIRST;
        int last = *last_str? atoi (last_str): DYNAMIC_LAST;

        //  This is how many times we'll try before giving up
        int attempts = last - first + 1;

        //  If operator is '*', take first available port.
        //  If operator is '!', take a random leap into our port space; we'll
        //  still scan sequentially to make sure we find a free slot rapidly.
        int port = first;
        if (streq (opcode, "!"))
            port += randof (attempts);
            
        rc = -1;                //  Assume we don't succeed
        while (rc == -1 && attempts--) {
            free (endpoint);
            endpoint = zsys_sprintf ("%s:%d", hostname, port);
            if (zmq_bind (self->handle, endpoint) == 0)
                rc = port;
            if (++port > last)
                port = first;
        }
    }
    else
        rc = zmq_bind (self->handle, endpoint);

    //  Store successful endpoint for later reference
    if (rc >= 0) {
        free (self->endpoint);
        self->endpoint = endpoint;
    }
    else
        free (endpoint);
    
    zrex_destroy (&rex);
    return rc;
}