/** * Run a standard GNUnet service startup sequence (initialize loggers * and configuration, parse options). * * @param argc number of command line arguments * @param argv command line arguments * @param service_name our service name * @param options service options * @param task main task of the service * @param task_cls closure for @a task * @return #GNUNET_SYSERR on error, #GNUNET_OK * if we shutdown nicely */ int GNUNET_SERVICE_run (int argc, char *const *argv, const char *service_name, enum GNUNET_SERVICE_Options options, GNUNET_SERVICE_Main task, void *task_cls) { #define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0) int err; int ret; char *cfg_fn; char *opt_cfg_fn; char *loglev; char *logfile; int do_daemonize; unsigned int i; unsigned long long skew_offset; unsigned long long skew_variance; long long clock_offset; struct GNUNET_SERVICE_Context sctx; struct GNUNET_CONFIGURATION_Handle *cfg; const char *xdg; struct GNUNET_GETOPT_CommandLineOption service_options[] = { GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn), {'d', "daemonize", NULL, gettext_noop ("do daemonize (detach from terminal)"), 0, GNUNET_GETOPT_set_one, &do_daemonize}, GNUNET_GETOPT_OPTION_HELP (NULL), GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev), GNUNET_GETOPT_OPTION_LOGFILE (&logfile), GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION), GNUNET_GETOPT_OPTION_END }; err = 1; do_daemonize = 0; logfile = NULL; loglev = NULL; opt_cfg_fn = NULL; xdg = getenv ("XDG_CONFIG_HOME"); if (NULL != xdg) GNUNET_asprintf (&cfg_fn, "%s%s%s", xdg, DIR_SEPARATOR_STR, GNUNET_OS_project_data_get ()->config_file); else cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file); memset (&sctx, 0, sizeof (sctx)); sctx.options = options; sctx.ready_confirm_fd = -1; sctx.ret = GNUNET_OK; sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL; sctx.task = task; sctx.task_cls = task_cls; sctx.service_name = service_name; sctx.cfg = cfg = GNUNET_CONFIGURATION_create (); /* setup subsystems */ ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv); if (GNUNET_SYSERR == ret) goto shutdown; if (GNUNET_NO == ret) { err = 0; goto shutdown; } if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile)) HANDLE_ERROR; if (NULL == opt_cfg_fn) opt_cfg_fn = GNUNET_strdup (cfg_fn); if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn)) { if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Malformed configuration file `%s', exit ...\n"), opt_cfg_fn); goto shutdown; } } else { if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Malformed configuration, exit ...\n")); goto shutdown; } if (0 != strcmp (opt_cfg_fn, cfg_fn)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access configuration file `%s'\n"), opt_cfg_fn); } if (GNUNET_OK != setup_service (&sctx)) goto shutdown; if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx))) HANDLE_ERROR; if (GNUNET_OK != set_user_id (&sctx)) goto shutdown; LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' runs with configuration from `%s'\n", service_name, opt_cfg_fn); if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING", "SKEW_OFFSET", &skew_offset)) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING", "SKEW_VARIANCE", &skew_variance))) { clock_offset = skew_offset - skew_variance; GNUNET_TIME_set_offset (clock_offset); LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); } /* actually run service */ err = 0; GNUNET_SCHEDULER_run (&service_task, &sctx); /* shutdown */ if ((1 == do_daemonize) && (NULL != sctx.server)) pid_file_delete (&sctx); GNUNET_free_non_null (sctx.my_handlers); shutdown: if (-1 != sctx.ready_confirm_fd) { if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1)) LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd)); } #if HAVE_MALLINFO { char *counter; if ( (GNUNET_YES == GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name, "GAUGER_HEAP")) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name, "GAUGER_HEAP", &counter)) ) { struct mallinfo mi; mi = mallinfo (); GAUGER (service_name, counter, mi.usmblks, "blocks"); GNUNET_free (counter); } } #endif GNUNET_SPEEDUP_stop_ (); GNUNET_CONFIGURATION_destroy (cfg); i = 0; if (NULL != sctx.addrs) while (NULL != sctx.addrs[i]) GNUNET_free (sctx.addrs[i++]); GNUNET_free_non_null (sctx.addrs); GNUNET_free_non_null (sctx.addrlens); GNUNET_free_non_null (logfile); GNUNET_free_non_null (loglev); GNUNET_free (cfg_fn); GNUNET_free_non_null (opt_cfg_fn); GNUNET_free_non_null (sctx.v4_denied); GNUNET_free_non_null (sctx.v6_denied); GNUNET_free_non_null (sctx.v4_allowed); GNUNET_free_non_null (sctx.v6_allowed); return err ? GNUNET_SYSERR : sctx.ret; }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_TESTING_Host *hosts; struct GNUNET_TESTING_Host *hostpos; struct GNUNET_TESTING_Host *temphost; char *hostfile; struct stat frstat; char *buf; char *data; int count; int ret; ok = 1; #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); #endif if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", &num_peers)) num_peers = DEFAULT_NUM_PEERS; GNUNET_assert (num_peers > 0 && num_peers < (unsigned long long) -1); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "hostfile", &hostfile)) hostfile = NULL; hosts = NULL; data = NULL; if (hostfile != NULL) { if (GNUNET_OK != GNUNET_DISK_file_test (hostfile)) GNUNET_DISK_fn_write (hostfile, NULL, 0, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if ((0 != STAT (hostfile, &frstat)) || (frstat.st_size == 0)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not open file specified for host list, ending test!"); ok = 1119; GNUNET_free (hostfile); return; } data = GNUNET_malloc_large (frstat.st_size); GNUNET_assert (data != NULL); if (frstat.st_size != GNUNET_DISK_fn_read (hostfile, data, frstat.st_size)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not read file %s specified for host list, ending test!", hostfile); GNUNET_free (hostfile); GNUNET_free (data); return; } GNUNET_free_non_null (hostfile); buf = data; count = 0; while (count < frstat.st_size) { count++; if (count >= frstat.st_size) break; /* if (((data[count] == '\n') || (data[count] == '\0')) && (buf != &data[count])) */ if (((data[count] == '\n')) && (buf != &data[count])) { data[count] = '\0'; temphost = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Host)); ret = SSCANF (buf, "%a[a-zA-Z0-9]@%a[a-zA-Z0-9.]:%hd", &temphost->username, &temphost->hostname, &temphost->port); if (3 == ret) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Successfully read host %s, port %d and user %s from file\n", temphost->hostname, temphost->port, temphost->username); } else { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Error reading line `%s' in hostfile\n", buf); GNUNET_free (temphost); buf = &data[count + 1]; continue; } /* temphost->hostname = buf; */ temphost->next = hosts; hosts = temphost; buf = &data[count + 1]; } else if ((data[count] == '\n') || (data[count] == '\0')) buf = &data[count + 1]; } } peers_left = num_peers; pg = GNUNET_TESTING_daemons_start (cfg, peers_left, /* Total number of peers */ peers_left, /* Number of outstanding connections */ peers_left, /* Number of parallel ssh connections, or peers being started at once */ TIMEOUT, NULL, NULL, &my_cb, NULL, NULL, NULL, hosts); hostpos = hosts; while (hostpos != NULL) { temphost = hostpos->next; GNUNET_free (hostpos->hostname); GNUNET_free (hostpos->username); GNUNET_free (hostpos); hostpos = temphost; } GNUNET_free_non_null (data); GNUNET_assert (pg != NULL); }
/** * A client specifically requested starting of ARM itself. * This function is called with information about whether * or not ARM is running; if it is, report success. If * it is not, start the ARM process. * * @param cls the context for the request that we will report on (struct ARMControlMessage *) * @param result GNUNET_YES if ARM is running */ static void arm_service_report (void *cls, int result) { struct ARMControlMessage *cm = cls; struct GNUNET_ARM_Handle *h; struct GNUNET_OS_Process *proc; unsigned char test_is_active; char *cbinary; char *binary; char *quotedbinary; char *config; char *loprefix; char *lopostfix; test_is_active = cm->h->service_test_is_active; if ((GNUNET_YES == test_is_active) && (GNUNET_YES == result)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n", "gnunet-service-arm"); /* arm is running! */ if (cm->result_cont) cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_IS_STARTED_ALREADY); } if (GNUNET_NO == test_is_active) { /* User disconnected & destroyed ARM handle in the middle of * the service test, so we kept the handle around until now. */ GNUNET_CONFIGURATION_destroy (cm->h->cfg); GNUNET_free (cm->h); } if ((GNUNET_YES == result) || (GNUNET_NO == test_is_active)) { GNUNET_free (cm); return; } cm->h->service_test_is_active = GNUNET_NO; LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is not running, will start it.\n", "gnunet-service-arm"); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string ( cm->h->cfg, "arm", "PREFIX", &loprefix)) loprefix = GNUNET_strdup (""); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string ( cm->h->cfg, "arm", "OPTIONS", &lopostfix)) lopostfix = GNUNET_strdup (""); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string ( cm->h->cfg, "arm", "BINARY", &cbinary)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, "arm", "BINARY"); if (cm->result_cont) cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_IS_NOT_KNOWN); GNUNET_free (cm); GNUNET_free (loprefix); GNUNET_free (lopostfix); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename ( cm->h->cfg, "arm", "CONFIG", &config)) config = NULL; binary = GNUNET_OS_get_libexec_binary_path (cbinary); GNUNET_asprintf ("edbinary, "\"%s\"", binary); GNUNET_free (cbinary); if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value ( cm->h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno ( cm->h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_NO == GNUNET_CONFIGURATION_have_value ( cm->h->cfg, "TESTING", "HOSTFILE"))) { /* Means we are ONLY running locally */ /* we're clearly running a test, don't daemonize */ if (NULL == config) proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance, NULL, loprefix, quotedbinary, /* no daemonization! */ lopostfix, NULL); else proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance, NULL, loprefix, quotedbinary, "-c", config, /* no daemonization! */ lopostfix, NULL); } else { if (NULL == config) proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance, NULL, loprefix, quotedbinary, "-d", lopostfix, NULL); else proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance, NULL, loprefix, quotedbinary, "-c", config, "-d", lopostfix, NULL); } GNUNET_free (binary); GNUNET_free (quotedbinary); GNUNET_free_non_null (config); GNUNET_free (loprefix); GNUNET_free (lopostfix); if (NULL == proc) { if (cm->result_cont) cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_START_FAILED); GNUNET_free (cm); return; } if (cm->result_cont) cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_STARTING); GNUNET_OS_process_destroy (proc); h = cm->h; GNUNET_free (cm); reconnect_arm (h); }
static void load_property (void *cls, const char *section) { struct GNUNET_CONFIGURATION_Handle *properties = cls; struct SysmonProperty *sp; char *tmp; if (NULL == strstr (section, "sysmon-")) return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading section `%s'\n", section); if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (properties, section, "TYPE")) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing value %s in section `%s'\n", "TYPE", section); return; } if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (properties, section,"VALUE")) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing value %s in section `%s'\n", "VALUE", section); return; } if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (properties, section,"DESCRIPTION")) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing value %s in section `%s'\n", "DESCRIPTION", section); return; } if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (properties, section,"CMD")) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing value %s in section `%s'\n", "CMD", section); return; } sp = GNUNET_malloc (sizeof (struct SysmonProperty)); /* description */ GNUNET_CONFIGURATION_get_value_string (properties, section, "DESCRIPTION", &sp->desc); /* cmd */ GNUNET_CONFIGURATION_get_value_string (properties, section, "CMD", &tmp); char *args = ""; if (NULL != strchr (tmp, ' ')) { args = strchr (tmp, ' '); if (strlen (args) > 1) { args[0] = '\0'; args++; } } sp->cmd = GNUNET_strdup (tmp); sp->cmd_args = GNUNET_strdup (args); GNUNET_free (tmp); sp->task = &exec_cmd; /* type */ GNUNET_CONFIGURATION_get_value_string (properties, section, "TYPE", &tmp); to_lower_str (tmp); if (0 == strcasecmp(tmp, "static")) sp->type = t_static; else if (0 == strcasecmp(tmp, "continous")) sp->type = t_continous; else { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid value %s for %s in section `%s'\n", tmp, "TYPE", section); GNUNET_free (tmp); GNUNET_free (sp); return; } GNUNET_free (tmp); /* value */ GNUNET_CONFIGURATION_get_value_string (properties, section, "VALUE", &tmp); to_lower_str (tmp); if (0 == strcasecmp(tmp, "numeric")) sp->value_type = v_numeric; else if (0 == strcasecmp(tmp, "string")) sp->value_type = v_string; else { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid value %s for %s in section `%s'\n", tmp, "VALUE", section); GNUNET_free (tmp); GNUNET_free (sp); return; } GNUNET_free (tmp); /* interval */ if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (properties, section,"INTERVAL")) sp->interval = GNUNET_TIME_UNIT_MINUTES; else { if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (properties, section, "INTERVAL", &sp->interval)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not parse execution interval for `%s', set to default 60 sec.\n"), section); sp->interval = GNUNET_TIME_UNIT_MINUTES; } } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded property `%s': %s, %s, interval %llu\n", (NULL != sp->desc) ? sp->desc: "<undefined>", (t_continous == sp->type) ? "continious" : "static", (v_numeric == sp->value_type) ? "numeric" : "string", sp->interval.rel_value); GNUNET_CONTAINER_DLL_insert (sp_head, sp_tail, sp); }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { char *quota_str; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", "a_str)) { fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n"); ret = 1; return; } if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_out)) { fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n"); ret = 1; GNUNET_free (quota_str); return; } GNUNET_free (quota_str); quota_str = NULL; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", "a_str)) { fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n"); ret = 1; return; } if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_in)) { fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n"); GNUNET_free (quota_str); ret = 1; return; } GNUNET_free (quota_str); quota_str = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN inbound quota: %llu\n", wan_quota_in); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN outbound quota: %llu\n", wan_quota_out); die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); /* Connect to ATS scheduling */ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL); if (sched_ats == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n"); ret = 1; end (); return; } perf_ats = GNUNET_ATS_performance_init (cfg, NULL, NULL); if (perf_ats == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS performance!\n"); ret = 1; end (); return; } /* Set up peer 0 */ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].id.hashPubKey)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n"); ret = GNUNET_SYSERR; end (); return; } GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p[0].id))); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", GNUNET_i2s(&p[0].id)); /* Set up peer 0 */ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].id.hashPubKey)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n"); ret = GNUNET_SYSERR; end (); return; } GNUNET_assert (0 == strcmp (PEERID1, GNUNET_i2s_full (&p[1].id))); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", GNUNET_i2s(&p[1].id)); /* Prepare ATS Information */ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE); test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN); test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); test_ats_info[1].value = htonl(1); test_ats_count = 2; /* Adding address with session */ test_session[0] = &test_addr[0]; create_test_address (&test_addr[0], "test0", test_session[0], "test0", strlen ("test0") + 1); test_hello_address[0].peer = p[0].id; test_hello_address[0].transport_name = test_addr[0].plugin; test_hello_address[0].address = test_addr[0].addr; test_hello_address[0].address_length = test_addr[0].addr_len; GNUNET_ATS_address_add (sched_ats, &test_hello_address[0], test_session[0], test_ats_info, test_ats_count); /* Adding address with session */ test_session[1] = &test_addr[1]; create_test_address (&test_addr[1], "test1", test_session[1], "test1", strlen ("test1") + 1); test_hello_address[1].peer = p[1].id; test_hello_address[1].transport_name = test_addr[0].plugin; test_hello_address[1].address = test_addr[0].addr; test_hello_address[1].address_length = test_addr[0].addr_len; GNUNET_ATS_address_add (sched_ats, &test_hello_address[1], test_session[1], test_ats_info, test_ats_count); /* Change bandwidth preference */ GNUNET_ATS_change_preference (perf_ats, &p[0].id, GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END); GNUNET_ATS_change_preference (perf_ats, &p[1].id, GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END); /* Change latency preference */ GNUNET_ATS_change_preference (perf_ats, &p[0].id, GNUNET_ATS_PREFERENCE_LATENCY,(double) 10, GNUNET_ATS_PREFERENCE_END); GNUNET_ATS_change_preference (perf_ats, &p[1].id, GNUNET_ATS_PREFERENCE_LATENCY,(double) 100, GNUNET_ATS_PREFERENCE_END); GNUNET_SCHEDULER_add_delayed (SLEEP, &sleep_task, NULL); }