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; }
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); }
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; }
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_; }
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; }
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); }
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; }
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"); }
/// // 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())); };
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); }
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; }
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"); }
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; }
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; }
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"); }
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"); }
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; }
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; }
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; }