static int testReadWrite () { char tmp[100 + 1]; int ret; if (strlen (TESTSTRING) != GNUNET_DISK_fn_write (".testfile", TESTSTRING, strlen (TESTSTRING), GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)) return 1; if (GNUNET_OK != GNUNET_DISK_file_test (".testfile")) return 1; ret = GNUNET_DISK_fn_read (".testfile", tmp, sizeof (tmp) - 1); if (ret < 0) { FPRINTF (stderr, "Error reading file `%s' in testReadWrite\n", ".testfile"); return 1; } tmp[ret] = '\0'; if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1)) { FPRINTF (stderr, "Error in testReadWrite: *%s* != *%s* for file %s\n", tmp, TESTSTRING, ".testfile"); return 1; } GNUNET_DISK_file_copy (".testfile", ".testfile2"); memset (tmp, 0, sizeof (tmp)); ret = GNUNET_DISK_fn_read (".testfile2", tmp, sizeof (tmp) - 1); if (ret < 0) { FPRINTF (stderr, "Error reading file `%s' in testReadWrite\n", ".testfile2"); return 1; } tmp[ret] = '\0'; if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1)) { FPRINTF (stderr, "Error in testReadWrite: *%s* != *%s* for file %s\n", tmp, TESTSTRING, ".testfile2"); return 1; } GNUNET_break (0 == UNLINK (".testfile")); GNUNET_break (0 == UNLINK (".testfile2")); if (GNUNET_NO != GNUNET_DISK_file_test (".testfile")) return 1; return 0; }
static void removecerts (const char *file1, const char *file2) { if (GNUNET_DISK_file_test (file1) == GNUNET_YES) { CHMOD (file1, S_IWUSR | S_IRUSR); REMOVE (file1); } if (GNUNET_DISK_file_test (file2) == GNUNET_YES) { CHMOD (file2, S_IWUSR | S_IRUSR); REMOVE (file2); } }
/** * Try to read the HELLO in the given filename and discard expired addresses. * * @param fn name of the file * @return HELLO of the file, NULL on error */ static struct GNUNET_HELLO_Message * read_host_file (const char *fn) { char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; const struct GNUNET_HELLO_Message *hello; struct GNUNET_HELLO_Message *hello_clean; int size; struct GNUNET_TIME_Absolute now; if (GNUNET_YES != GNUNET_DISK_file_test (fn)) return NULL; size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); hello = (const struct GNUNET_HELLO_Message *) buffer; if ((size < sizeof (struct GNUNET_MessageHeader)) || (size != ntohs ((((const struct GNUNET_MessageHeader *) hello)->size))) || (size != GNUNET_HELLO_size (hello))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse HELLO in file `%s'\n"), fn); return NULL; } now = GNUNET_TIME_absolute_get (); hello_clean = GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, &now); return hello_clean; }
/** * @brief Restore the peers on disk to #valid_peers. */ static void restore_valid_peers () { off_t file_size; uint32_t num_peers; struct GNUNET_DISK_FileHandle *fh; char *buf; ssize_t size_read; char *iter_buf; char *str_repr; const struct GNUNET_PeerIdentity *peer; if (0 == strncmp ("DISABLE", filename_valid_peers, 7)) { return; } if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers)) { return; } fh = GNUNET_DISK_file_open (filename_valid_peers, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); GNUNET_assert (NULL != fh); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size)); num_peers = file_size / 53; buf = GNUNET_malloc (file_size); size_read = GNUNET_DISK_file_read (fh, buf, file_size); GNUNET_assert (size_read == file_size); LOG (GNUNET_ERROR_TYPE_DEBUG, "Restoring %" PRIu32 " peers from file `%s'\n", num_peers, filename_valid_peers); for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53) { str_repr = GNUNET_strndup (iter_buf, 53); peer = s2i_full (str_repr); GNUNET_free (str_repr); add_valid_peer (peer); LOG (GNUNET_ERROR_TYPE_DEBUG, "Restored valid peer %s from disk\n", GNUNET_i2s_full (peer)); } iter_buf = NULL; GNUNET_free (buf); LOG (GNUNET_ERROR_TYPE_DEBUG, "num_peers: %" PRIu32 ", _size (valid_peers): %u\n", num_peers, GNUNET_CONTAINER_multipeermap_size (valid_peers)); if (num_peers != GNUNET_CONTAINER_multipeermap_size (valid_peers)) { LOG (GNUNET_ERROR_TYPE_WARNING, "Number of restored peers does not match file size. Have probably duplicates.\n"); } GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Restored %u valid peers from disk\n", GNUNET_CONTAINER_multipeermap_size (valid_peers)); }
int main (int argc, char *argv[]) { int ret; GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); GNUNET_log_setup ("test-gnunet-daemon-hostlist", "WARNING", NULL); #if !WINDOWS system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > /dev/null"); system ("gnunet-peerinfo -s -c test_learning_learn_peer.conf > /dev/null"); #else system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > NUL"); system ("gnunet-peerinfo -s -c test_learning_learn_peer.conf > NUL"); #endif ret = check (); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); if (GNUNET_YES == GNUNET_DISK_file_test ("hostlists_learn_peer.file")) { if (0 == UNLINK ("hostlists_learn_peer.file")) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Hostlist file hostlists_learn_peer.file was removed\n"); } return ret; }
void delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg) { char *afsdir; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite", "FILENAME", &afsdir)) { if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) if (GNUNET_OK == GNUNET_DISK_file_test (afsdir)) if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir)) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir); GNUNET_free (afsdir); } }
/** * read the pseudonym infomation from a file * @param cfg configuration to use * @param nsid hash code of a pseudonym * @param meta meta data to be read from a file * @param ranking ranking of a pseudonym * @param ns_name name of a pseudonym */ static int read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **meta, int32_t * ranking, char **ns_name) { char *fn; char *emsg; struct GNUNET_BIO_ReadHandle *fileR; fn = get_data_filename (cfg, PS_METADATA_DIR, nsid); GNUNET_assert (fn != NULL); if (GNUNET_YES != GNUNET_DISK_file_test (fn)) { GNUNET_free (fn); return GNUNET_SYSERR; } fileR = GNUNET_BIO_read_open (fn); if (fileR == NULL) { GNUNET_free (fn); return GNUNET_SYSERR; } emsg = NULL; *ns_name = NULL; if ((GNUNET_OK != GNUNET_BIO_read_int32 (fileR, ranking)) || (GNUNET_OK != GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) || (GNUNET_OK != GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta))) { (void) GNUNET_BIO_read_close (fileR, &emsg); GNUNET_free_non_null (emsg); GNUNET_free_non_null (*ns_name); *ns_name = NULL; GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); GNUNET_free (fn); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to parse metadata about pseudonym from file `%s': %s\n"), fn, emsg); GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); GNUNET_CONTAINER_meta_data_destroy (*meta); *meta = NULL; GNUNET_free_non_null (*ns_name); *ns_name = NULL; GNUNET_free_non_null (emsg); GNUNET_free (fn); return GNUNET_SYSERR; } GNUNET_free (fn); return GNUNET_OK; }
int main (int argc, char *argv[]) { GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name); GNUNET_log_setup (test_name, "WARNING", NULL); GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source); GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source, &test_plugin); tth = GNUNET_TRANSPORT_TESTING_init (); GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1); GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2); check (); GNUNET_free (cfg_file_p1); GNUNET_free (cfg_file_p2); if (GNUNET_YES == GNUNET_DISK_file_test (gen_cfg_p1)) { GNUNET_DISK_directory_remove (gen_cfg_p1); GNUNET_free (gen_cfg_p1); } if (GNUNET_YES == GNUNET_DISK_file_test (gen_cfg_p2)) { GNUNET_DISK_directory_remove (gen_cfg_p2); GNUNET_free (gen_cfg_p2); } GNUNET_free (test_source); GNUNET_free (test_plugin); GNUNET_free (test_name); GNUNET_TRANSPORT_TESTING_done (tth); return test_failed; }
/** * Get the namespace ID belonging to the given namespace name. * * @param cfg configuration to use * @param ns_uname unique (!) human-readable name for the namespace * @param nsid set to namespace ID based on 'ns_uname' * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ int GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *ns_uname, struct GNUNET_HashCode * nsid) { size_t slen; uint64_t len; unsigned int idx; char *name; struct GNUNET_HashCode nh; char *fn; struct GNUNET_DISK_FileHandle *fh; idx = -1; slen = strlen (ns_uname); while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx))) slen--; if (slen == 0) return GNUNET_SYSERR; name = GNUNET_strdup (ns_uname); name[slen - 1] = '\0'; GNUNET_CRYPTO_hash (name, strlen (name), &nh); GNUNET_free (name); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || ((idx + 1) * sizeof (struct GNUNET_HashCode) > len)) { GNUNET_free (fn); return GNUNET_SYSERR; } fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); GNUNET_free (fn); if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_HashCode), GNUNET_DISK_SEEK_SET)) { GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } if (sizeof (struct GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof (struct GNUNET_HashCode))) { GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } GNUNET_DISK_file_close (fh); return GNUNET_OK; }
/** * Handle network size estimate clients. * * @param cls closure * @param server the initialized server * @param c configuration to use */ static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service) { cfg = c; nc = GNUNET_notification_context_create (1); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "identity", "EGODIR", &ego_directory)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR"); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "identity", "SUBSYSTEM_CFG", &subsystem_cfg_file)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "SUBSYSTEM_CFG"); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading subsystem configuration `%s'\n", subsystem_cfg_file); subsystem_cfg = GNUNET_CONFIGURATION_create (); if ( (GNUNET_YES == GNUNET_DISK_file_test (subsystem_cfg_file)) && (GNUNET_OK != GNUNET_CONFIGURATION_parse (subsystem_cfg, subsystem_cfg_file)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse subsystem identity configuration file `%s'\n"), subsystem_cfg_file); GNUNET_SCHEDULER_shutdown (); return; } stats = GNUNET_STATISTICS_create ("identity", cfg); if (GNUNET_OK != GNUNET_DISK_directory_create (ego_directory)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to create directory `%s' for storing egos\n"), ego_directory); } GNUNET_DISK_directory_scan (ego_directory, &process_ego_file, NULL); GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); }
static int testDirMani () { if (GNUNET_OK != GNUNET_DISK_directory_create_for_file ("test/ing")) return 1; if (GNUNET_NO != GNUNET_DISK_file_test ("test")) return 1; if (GNUNET_NO != GNUNET_DISK_file_test ("test/ing")) return 1; if (GNUNET_OK != GNUNET_DISK_directory_remove ("test")) return 1; if (GNUNET_OK != GNUNET_DISK_directory_create ("test")) return 1; if (GNUNET_YES != GNUNET_DISK_directory_test ("test", GNUNET_YES)) return 1; if (GNUNET_OK != GNUNET_DISK_directory_remove ("test")) return 1; return 0; }
/** * Function that is called on each HELLO file in a particular directory. * Try to parse the file and add the HELLO to our list. * * @param cls pointer to 'unsigned int' to increment for each file, or NULL * if the file is from a read-only, read-once resource directory * @param fullname name of the file to parse * @return GNUNET_OK (continue iteration) */ static int hosts_directory_scan_callback (void *cls, const char *fullname) { unsigned int *matched = cls; struct GNUNET_PeerIdentity identity; const char *filename; struct HostEntry *entry; struct GNUNET_HELLO_Message *hello; if (GNUNET_DISK_file_test (fullname) != GNUNET_YES) return GNUNET_OK; /* ignore non-files */ if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) { if (NULL != matched) remove_garbage (fullname); return GNUNET_OK; } filename = &fullname[strlen (fullname) - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1]; if (filename[-1] != DIR_SEPARATOR) { if (NULL != matched) remove_garbage (fullname); return GNUNET_OK; } if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey)) { if (NULL != (hello = read_host_file (filename))) { entry = GNUNET_malloc (sizeof (struct HostEntry)); if (GNUNET_OK == GNUNET_HELLO_get_id (hello, &entry->identity)) { GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); entry->hello = hello; notify_all (entry); return GNUNET_OK; } GNUNET_free (entry); } if (NULL != matched) remove_garbage (fullname); return GNUNET_OK; } if (NULL != matched) (*matched)++; add_host_to_known_hosts (&identity); return GNUNET_OK; }
/** * Lookup the private key for the zone * * @param zone the zone we want a private key for * @return NULL of not found else the key */ struct GNUNET_CRYPTO_RsaPrivateKey* lookup_private_key(struct GNUNET_CRYPTO_ShortHashCode *zone) { char* keydir; struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename; char* location; struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Looking for private key\n"); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (GNS_cfg, "namestore", "ZONEFILE_DIRECTORY", &keydir)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zonefile directory!\n"); return NULL; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Zonefile directory is %s\n", keydir); GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Zonefile is %s.zkey\n", &zonename); GNUNET_asprintf(&location, "%s%s%s.zkey", keydir, DIR_SEPARATOR_STR, &zonename); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Checking for %s\n", location); if (GNUNET_YES == GNUNET_DISK_file_test (location)) key = GNUNET_CRYPTO_rsa_key_create_from_file (location); GNUNET_free(location); GNUNET_free(keydir); return key; }
static void setup_learn_peer (struct PeerContext *p, const char *cfgname) { char *filename; unsigned int result; char *binary; binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm"); p->cfg = GNUNET_CONFIGURATION_create (); p->arm_proc = GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, NULL, binary, "gnunet-service-arm", "-c", cfgname, NULL); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (p->cfg, "HOSTLIST", "HOSTLISTFILE", &filename)) { if (GNUNET_YES == GNUNET_DISK_file_test (filename)) { result = UNLINK (filename); if (result == 0) GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Hostlist file `%s' was removed\n"), filename); } GNUNET_free (filename); } p->core = GNUNET_CORE_connect (p->cfg, NULL, NULL, NULL, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, learn_handlers); GNUNET_assert (NULL != p->core); p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg); GNUNET_assert (NULL != p->stats); GNUNET_free (binary); }
/** * Read index information from disk. */ static void read_index_list () { struct GNUNET_BIO_ReadHandle *rh; char *fn; struct IndexInfo *pos; char *fname; struct GNUNET_HashCode hc; size_t slen; char *emsg; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "FS", "INDEXDB", &fn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "fs", "INDEXDB"); return; } if (GNUNET_NO == GNUNET_DISK_file_test (fn)) { /* no index info yet */ GNUNET_free (fn); return; } rh = GNUNET_BIO_read_open (fn); if (NULL == rh) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, _("Could not open `%s'.\n"), fn); GNUNET_free (fn); return; } while ((GNUNET_OK == GNUNET_BIO_read (rh, "Hash of indexed file", &hc, sizeof (struct GNUNET_HashCode))) && (GNUNET_OK == GNUNET_BIO_read_string (rh, "Name of indexed file", &fname, 1024 * 16)) && (fname != NULL)) { slen = strlen (fname) + 1; pos = GNUNET_malloc (sizeof (struct IndexInfo) + slen); pos->file_id = hc; pos->filename = (const char *) &pos[1]; memcpy (&pos[1], fname, slen); if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (ifm, &pos->file_id, pos, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { GNUNET_free (pos); } else { GNUNET_CONTAINER_DLL_insert (indexed_files_head, indexed_files_tail, pos); } GNUNET_free (fname); } if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) GNUNET_free (emsg); GNUNET_free (fn); }
/** * 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.conf"); else cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_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; }
/** * Initialize the database connections and associated * data structures (create tables and indices * as needed as well). * * @param plugin the plugin context (state for this module) * @return GNUNET_OK on success */ static int database_setup (struct Plugin *plugin) { char *afsdir; char *key; char *sub_system; const char *peer_id; char *peer; char *value; char *expiry; struct GNUNET_DISK_FileHandle *fh; struct GNUNET_PEERSTORE_Record *entry; struct GNUNET_HashCode hkey; size_t size; char *buffer; char *line; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-flat", "FILENAME", &afsdir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-flat", "FILENAME"); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) { if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir)) { GNUNET_break (0); GNUNET_free (afsdir); return GNUNET_SYSERR; } } /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */ plugin->fn = afsdir; fh = GNUNET_DISK_file_open (afsdir, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ); if (NULL == fh) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize file: %s.\n"), afsdir); return GNUNET_SYSERR; } /* Load data from file into hashmap */ plugin->hm = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir, &size, GNUNET_YES, GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to get filesize: %s.\n"), afsdir); return GNUNET_SYSERR; } buffer = GNUNET_malloc (size + 1); if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh, buffer, size)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to read file: %s.\n"), afsdir); GNUNET_DISK_file_close (fh); GNUNET_free (buffer); return GNUNET_SYSERR; } buffer[size] = '\0'; GNUNET_DISK_file_close (fh); if (0 < size) { line = strtok (buffer, "\n"); while (line != NULL) { sub_system = strtok (line, ","); if (NULL == sub_system) break; peer = strtok (NULL, ","); if (NULL == peer) break; key = strtok (NULL, ","); if (NULL == key) break; value = strtok (NULL, ","); if (NULL == value) break; expiry = strtok (NULL, ","); if (NULL == expiry) break; entry = GNUNET_new (struct GNUNET_PEERSTORE_Record); entry->sub_system = GNUNET_strdup (sub_system); entry->key = GNUNET_strdup (key); GNUNET_STRINGS_base64_decode (peer, strlen (peer), (char**)&entry->peer); entry->value_size = GNUNET_STRINGS_base64_decode (value, strlen (value), (char**)&entry->value); if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_absolute (expiry, entry->expiry)) { GNUNET_free (entry->sub_system); GNUNET_free (entry->key); GNUNET_free (entry->peer); GNUNET_free (entry); break; } peer_id = GNUNET_i2s (entry->peer); GNUNET_CRYPTO_hash (peer_id, strlen (peer_id), &hkey); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (plugin->hm, &hkey, entry, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); } }
/** * Initialize the database connections and associated * data structures (create tables and indices * as needed as well). * * @param plugin the plugin context (state for this module) * @return GNUNET_OK on success */ static int database_setup (struct Plugin *plugin) { char *filename; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-sqlite", "FILENAME", &filename)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-sqlite", "FILENAME"); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_DISK_file_test (filename)) { if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename)) { GNUNET_break (0); GNUNET_free (filename); return GNUNET_SYSERR; } } /* filename should be UTF-8-encoded. If it isn't, it's a bug */ plugin->fn = filename; /* Open database and precompile statements */ if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize SQLite: %s.\n"), sqlite3_errmsg (plugin->dbh)); return GNUNET_SYSERR; } sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); sql_exec (plugin->dbh, "PRAGMA synchronous=OFF"); sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL"); sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\""); sql_exec (plugin->dbh, "PRAGMA page_size=4096"); sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS); /* Create tables */ sql_exec (plugin->dbh, "CREATE TABLE IF NOT EXISTS peerstoredata (\n" " sub_system TEXT NOT NULL,\n" " peer_id BLOB NOT NULL,\n" " key TEXT NOT NULL,\n" " value BLOB NULL,\n" " expiry sqlite3_uint64 NOT NULL" ");"); sqlite3_create_function (plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL, &sqlite3_lessthan, NULL, NULL); /* Create Indices */ if (SQLITE_OK != sqlite3_exec (plugin->dbh, "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)", NULL, NULL, NULL)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to create indices: %s.\n"), sqlite3_errmsg (plugin->dbh)); return GNUNET_SYSERR; } /* Prepare statements */ sql_prepare (plugin->dbh, "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry) VALUES (?,?,?,?,?);", &plugin->insert_peerstoredata); sql_prepare (plugin->dbh, "SELECT * FROM peerstoredata" " WHERE sub_system = ?", &plugin->select_peerstoredata); sql_prepare (plugin->dbh, "SELECT * FROM peerstoredata" " WHERE sub_system = ?" " AND peer_id = ?", &plugin->select_peerstoredata_by_pid); sql_prepare (plugin->dbh, "SELECT * FROM peerstoredata" " WHERE sub_system = ?" " AND key = ?", &plugin->select_peerstoredata_by_key); sql_prepare (plugin->dbh, "SELECT * FROM peerstoredata" " WHERE sub_system = ?" " AND peer_id = ?" " AND key = ?", &plugin->select_peerstoredata_by_all); sql_prepare (plugin->dbh, "DELETE FROM peerstoredata" " WHERE UINT64_LT(expiry, ?)", &plugin->expire_peerstoredata); sql_prepare (plugin->dbh, "DELETE FROM peerstoredata" " WHERE sub_system = ?" " AND peer_id = ?" " AND key = ?", &plugin->delete_peerstoredata); return GNUNET_OK; }
/** * Main function that will be run by the scheduler. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param cfg configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { struct GNUNET_CRYPTO_EddsaPrivateKey *pk; char *pids; cfg = config; /* load proof of work */ if (NULL == pwfn) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &pwfn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE"); GNUNET_SCHEDULER_shutdown (); return; } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Proof of Work file: %s\n", pwfn); if ( (GNUNET_YES != GNUNET_DISK_file_test (pwfn)) || (sizeof (proof) != GNUNET_DISK_fn_read (pwfn, &proof, sizeof (proof)))) proof = 0; /* load private key */ if (NULL == pkfn) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &pkfn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "PEER", "PRIVATE_KEY"); return; } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn); if (NULL == (pk = GNUNET_CRYPTO_eddsa_key_create_from_file (pkfn))) { FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), pkfn); GNUNET_free (pkfn); return; } GNUNET_free (pkfn); GNUNET_CRYPTO_eddsa_key_get_public (pk, &pub); GNUNET_free (pk); pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peer ID: %s\n", pids); GNUNET_free (pids); /* get target bit amount */ if (0 == nse_work_required) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS", &nse_work_required)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS"); GNUNET_SCHEDULER_shutdown (); return; } if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS", _("Value is too large.\n")); GNUNET_SCHEDULER_shutdown (); return; } else if (0 == nse_work_required) { write_proof (); GNUNET_SCHEDULER_shutdown (); return; } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bits: %llu\n", nse_work_required); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delay between tries: %s\n", GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1)); GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); }
/** * Read the friends file. */ static void read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg) { char *fn; char *data; size_t pos; struct GNUNET_PeerIdentity pid; uint64_t fsize; struct GNUNET_CRYPTO_HashAsciiEncoded enc; unsigned int entries_found; struct Peer *fl; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "TOPOLOGY", "FRIENDS", &fn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "topology", "FRIENDS"); return; } if (GNUNET_OK != GNUNET_DISK_file_test (fn)) GNUNET_DISK_fn_write (fn, NULL, 0, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (GNUNET_OK != GNUNET_DISK_file_size (fn, &fsize, GNUNET_NO, GNUNET_YES)) { if ((friends_only) || (minimum_friend_count > 0)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not read friends list `%s'\n"), fn); GNUNET_free (fn); return; } if (fsize == 0) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Friends file `%s' is empty.\n"), fn); GNUNET_free (fn); return; } data = GNUNET_malloc_large (fsize); if (data == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read friends list from `%s': out of memory\n"), fn); GNUNET_free (fn); return; } if (fsize != GNUNET_DISK_fn_read (fn, data, fsize)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read friends list from `%s'\n"), fn); GNUNET_free (fn); GNUNET_free (data); return; } entries_found = 0; pos = 0; while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; while ((fsize >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && (pos <= fsize - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) { memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); if (!isspace ((unsigned char) enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Syntax error in topology specification at offset %llu, skipping bytes.\n"), (unsigned long long) pos); pos++; while ((pos < fsize) && (!isspace ((unsigned char) data[pos]))) pos++; continue; } enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n"), (unsigned long long) pos, &enc); } else { if (0 != memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity))) { entries_found++; fl = make_peer (&pid, NULL, GNUNET_YES); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Found friend `%s' in configuration\n"), GNUNET_i2s (&fl->pid)); } else { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Found myself `%s' in friend list (useless, ignored)\n"), GNUNET_i2s (&pid)); } } pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); while ((pos < fsize) && isspace ((unsigned char) data[pos])) pos++; } GNUNET_free (data); GNUNET_free (fn); GNUNET_STATISTICS_update (stats, gettext_noop ("# friends in configuration"), entries_found, GNUNET_NO); if ((minimum_friend_count > entries_found) && (friends_only == GNUNET_NO)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n")); } if ((minimum_friend_count > target_connection_count) && (friends_only == GNUNET_NO)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("More friendly connections required than target total number of connections.\n")); } }
/** * Handle network size estimate clients. * * @param cls closure * @param server the initialized server * @param c configuration to use */ static void run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { static const struct GNUNET_SERVER_MessageHandler handlers[] = { {&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_IDENTITY_START, sizeof (struct GNUNET_MessageHeader)}, {&handle_get_default_message, NULL, GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, 0}, {&handle_set_default_message, NULL, GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, 0}, {&handle_create_message, NULL, GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, 0}, {&handle_rename_message, NULL, GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, 0}, {&handle_delete_message, NULL, GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, 0}, {NULL, NULL, 0, 0} }; cfg = c; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "identity", "EGODIR", &ego_directory)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR"); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "identity", "SUBSYSTEM_CFG", &subsystem_cfg_file)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "SUBSYSTEM_CFG"); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading subsystem configuration `%s'\n", subsystem_cfg_file); subsystem_cfg = GNUNET_CONFIGURATION_create (); if ( (GNUNET_YES == GNUNET_DISK_file_test (subsystem_cfg_file)) && (GNUNET_OK != GNUNET_CONFIGURATION_parse (subsystem_cfg, subsystem_cfg_file)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse subsystem identity configuration file `%s'\n"), subsystem_cfg_file); GNUNET_SCHEDULER_shutdown (); return; } stats = GNUNET_STATISTICS_create ("identity", cfg); GNUNET_SERVER_add_handlers (server, handlers); nc = GNUNET_SERVER_notification_context_create (server, 1); if (GNUNET_OK != GNUNET_DISK_directory_create (ego_directory)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to create directory `%s' for storing egos\n"), ego_directory); } GNUNET_DISK_directory_scan (ego_directory, &process_ego_file, NULL); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); }
/** * Initialize the database connections and associated * data structures (create tables and indices * as needed as well). * * @param cfg our configuration * @param plugin the plugin context (state for this module) * @return GNUNET_OK on success */ static int database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, struct Plugin *plugin) { sqlite3_stmt *stmt; char *afsdir; #if ENULL_DEFINED char *e; #endif if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "datastore-sqlite", "FILENAME", &afsdir)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite", _ ("Option `%s' in section `%s' missing in configuration!\n"), "FILENAME", "datastore-sqlite"); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) { if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir)) { GNUNET_break (0); GNUNET_free (afsdir); return GNUNET_SYSERR; } /* database is new or got deleted, reset payload to zero! */ plugin->env->duc (plugin->env->cls, 0); } #ifdef ENABLE_NLS plugin->fn = GNUNET_STRINGS_to_utf8 (afsdir, strlen (afsdir), nl_langinfo (CODESET)); #else plugin->fn = GNUNET_STRINGS_to_utf8 (afsdir, strlen (afsdir), "UTF-8"); /* good luck */ #endif GNUNET_free (afsdir); /* Open database and precompile statements */ if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite", _("Unable to initialize SQLite: %s.\n"), sqlite3_errmsg (plugin->dbh)); return GNUNET_SYSERR; } CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA count_changes=OFF", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS)); /* We have to do it here, because otherwise precompiling SQL might fail */ CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'", &stmt)); if ((sqlite3_step (stmt) == SQLITE_DONE) && (sqlite3_exec (plugin->dbh, "CREATE TABLE gn090 (" " repl INT4 NOT NULL DEFAULT 0," " type INT4 NOT NULL DEFAULT 0," " prio INT4 NOT NULL DEFAULT 0," " anonLevel INT4 NOT NULL DEFAULT 0," " expire INT8 NOT NULL DEFAULT 0," " rvalue INT8 NOT NULL," " hash TEXT NOT NULL DEFAULT ''," " vhash TEXT NOT NULL DEFAULT ''," " value BLOB NOT NULL DEFAULT '')", NULL, NULL, NULL) != SQLITE_OK)) { LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec"); sqlite3_finalize (stmt); return GNUNET_SYSERR; } sqlite3_finalize (stmt); create_indices (plugin->dbh); if ((sq_prepare (plugin->dbh, "UPDATE gn090 " "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?", &plugin->updPrio) != SQLITE_OK) || (sq_prepare (plugin->dbh, "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?", &plugin->updRepl) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " #if SQLITE_VERSION_NUMBER >= 3007000 "INDEXED BY idx_repl_rvalue " #endif "WHERE repl=?2 AND " " (rvalue>=?1 OR " " NOT EXISTS (SELECT 1 FROM gn090 " #if SQLITE_VERSION_NUMBER >= 3007000 "INDEXED BY idx_repl_rvalue " #endif "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) " "ORDER BY rvalue ASC LIMIT 1", &plugin->selRepl) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT MAX(repl) FROM gn090" #if SQLITE_VERSION_NUMBER >= 3007000 " INDEXED BY idx_repl_rvalue" #endif "", &plugin->maxRepl) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " #if SQLITE_VERSION_NUMBER >= 3007000 "INDEXED BY idx_expire " #endif "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) " "ORDER BY expire ASC LIMIT 1", &plugin->selExpi) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " #if SQLITE_VERSION_NUMBER >= 3007000 "INDEXED BY idx_anon_type_hash " #endif "WHERE (anonLevel = 0 AND type=?1) " "ORDER BY hash DESC LIMIT 1 OFFSET ?2", &plugin->selZeroAnon) != SQLITE_OK) || (sq_prepare (plugin->dbh, "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", &plugin->insertContent) != SQLITE_OK) || (sq_prepare (plugin->dbh, "DELETE FROM gn090 WHERE _ROWID_ = ?", &plugin->delRow) != SQLITE_OK)) { LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "precompiling"); return GNUNET_SYSERR; } return GNUNET_OK; }
/** * Handle network size estimate clients. * * @param cls closure * @param c configuration to use * @param service the initialized service */ static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service) { struct GNUNET_MQ_MessageHandler core_handlers[] = { GNUNET_MQ_hd_fixed_size (p2p_estimate, GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD, struct GNUNET_NSE_FloodMessage, NULL), GNUNET_MQ_handler_end () }; char *proof; struct GNUNET_CRYPTO_EddsaPrivateKey *pk; cfg = c; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL", &gnunet_nse_interval)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "INTERVAL"); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY", &proof_find_delay)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKDELAY"); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS", &nse_work_required)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS"); GNUNET_SCHEDULER_shutdown (); return; } if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS", _("Value is too large.\n")); GNUNET_SCHEDULER_shutdown (); return; } #if ENABLE_NSE_HISTOGRAM { char *histogram_dir; char *histogram_fn; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "HISTOGRAM_DIR", &histogram_dir)) { GNUNET_assert (0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir)); GNUNET_free (histogram_dir); histogram = GNUNET_BIO_write_open (histogram_fn); if (NULL == histogram) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to open histogram file `%s'\n", histogram_fn); GNUNET_free (histogram_fn); } logger_test = GNUNET_CLIENT_service_test ("testbed-logger", cfg, GNUNET_TIME_UNIT_SECONDS, &status_cb, NULL); } #endif GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); pk = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); GNUNET_assert (NULL != pk); my_private_key = pk; GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE"); GNUNET_free (my_private_key); my_private_key = NULL; GNUNET_SCHEDULER_shutdown (); return; } if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) || (sizeof (my_proof) != GNUNET_DISK_fn_read (proof, &my_proof, sizeof (my_proof)))) my_proof = 0; GNUNET_free (proof); proof_task = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); nc = GNUNET_notification_context_create (1); /* Connect to core service and register core handlers */ core_api = GNUNET_CORE_connect (cfg, /* Main configuration */ NULL, /* Closure passed to functions */ &core_init, /* Call core_init once connected */ &handle_core_connect, /* Handle connects */ &handle_core_disconnect, /* Handle disconnects */ core_handlers); /* Register these handlers */ if (NULL == core_api) { GNUNET_SCHEDULER_shutdown (); return; } stats = GNUNET_STATISTICS_create ("nse", cfg); }
/** * Load a set of hosts from a configuration file. * * @param filename file with the host specification * @param cfg the configuration to use as a template while starting a controller * on any of the loaded hosts. Operation queue sizes specific to a host * are also read from this configuration handle * @param hosts set to the hosts found in the file; caller must free this if * number of hosts returned is greater than 0 * @return number of hosts returned in 'hosts', 0 on error */ unsigned int GNUNET_TESTBED_hosts_load_from_file (const char *filename, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTBED_Host ***hosts) { //struct GNUNET_TESTBED_Host **host_array; struct GNUNET_TESTBED_Host *starting_host; char *data; char *buf; char *username; char *hostname; regex_t rex; regmatch_t pmatch[6]; uint64_t fs; short int port; unsigned int offset; unsigned int count; GNUNET_assert (NULL != filename); if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s not found\n"), filename); return 0; } if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; if (0 == fs) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s has no data\n"), filename); return 0; } data = GNUNET_malloc (fs); if (fs != GNUNET_DISK_fn_read (filename, data, fs)) { GNUNET_free (data); LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s cannot be read\n"), filename); return 0; } buf = data; offset = 0; starting_host = NULL; count = 0; /* refer RFC 952 and RFC 1123 for valid hostnames */ GNUNET_assert (0 == regcomp (&rex, "^(([[:alnum:]]+)@)?" /* username */ "([[:alnum:]]+[-[:alnum:]_\\.]+)" /* hostname */ "(:([[:digit:]]{1,5}))?", /* port */ REG_EXTENDED | REG_ICASE)); while (offset < (fs - 1)) { offset++; if (((data[offset] == '\n')) && (buf != &data[offset])) { unsigned int size; data[offset] = '\0'; username = NULL; hostname = NULL; port = 0; if ((REG_NOMATCH == regexec (&rex, buf, 6, pmatch, 0)) || (-1 == pmatch[3].rm_so)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Error reading line `%s' in hostfile\n", buf); buf = &data[offset + 1]; continue; } if (-1 != pmatch[2].rm_so) { size = pmatch[2].rm_eo - pmatch[2].rm_so; username = GNUNET_malloc (size + 1); username[size] = '\0'; GNUNET_assert (NULL != strncpy (username, buf + pmatch[2].rm_so, size)); } if (-1 != pmatch[5].rm_so) { (void) SSCANF (buf + pmatch[5].rm_so, "%5hd", &port); } size = pmatch[3].rm_eo - pmatch[3].rm_so; hostname = GNUNET_malloc (size + 1); hostname[size] = '\0'; GNUNET_assert (NULL != strncpy (hostname, buf + pmatch[3].rm_so, size)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Successfully read host %s, port %d and user %s from file\n", (NULL == hostname) ? "NULL" : hostname, port, (NULL == username) ? "NULL" : username); /* We store hosts in a static list; hence we only require the starting * host pointer in that list to access the newly created list of hosts */ if (NULL == starting_host) starting_host = GNUNET_TESTBED_host_create (hostname, username, cfg, port); else (void) GNUNET_TESTBED_host_create (hostname, username, cfg, port); count++; GNUNET_free_non_null (username); GNUNET_free (hostname); buf = &data[offset + 1]; } else if ((data[offset] == '\n') || (data[offset] == '\0')) buf = &data[offset + 1]; } regfree (&rex); GNUNET_free (data); if (NULL == starting_host) return 0; *hosts = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Host *) * count); memcpy (*hosts, &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)], sizeof (struct GNUNET_TESTBED_Host *) * count); return count; }
/** * Initialize the database connections and associated * data structures (create tables and indices * as needed as well). * * @param plugin the plugin context (state for this module) * @return #GNUNET_OK on success */ static int database_setup (struct Plugin *plugin) { sqlite3_stmt *stmt; char *afsdir; #if ENULL_DEFINED char *e; #endif if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namecache-sqlite", "FILENAME", &afsdir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "namecache-sqlite", "FILENAME"); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) { if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir)) { GNUNET_break (0); GNUNET_free (afsdir); return GNUNET_SYSERR; } } /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */ plugin->fn = afsdir; /* Open database and precompile statements */ if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize SQLite: %s.\n"), sqlite3_errmsg (plugin->dbh)); return GNUNET_SYSERR; } CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA synchronous=NORMAL", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL, ENULL)); CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS)); /* Create tables */ CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'", &stmt)); if ((sqlite3_step (stmt) == SQLITE_DONE) && (sqlite3_exec (plugin->dbh, "CREATE TABLE ns096blocks (" " query BLOB NOT NULL DEFAULT ''," " block BLOB NOT NULL DEFAULT ''," " expiration_time INT8 NOT NULL DEFAULT 0" ")", NULL, NULL, NULL) != SQLITE_OK)) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec"); sqlite3_finalize (stmt); return GNUNET_SYSERR; } sqlite3_finalize (stmt); create_indices (plugin->dbh); if ((sq_prepare (plugin->dbh, "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)", &plugin->cache_block) != SQLITE_OK) || (sq_prepare (plugin->dbh, "DELETE FROM ns096blocks WHERE expiration_time<?", &plugin->expire_blocks) != SQLITE_OK) || (sq_prepare (plugin->dbh, "DELETE FROM ns096blocks WHERE query=? AND expiration_time<=?", &plugin->delete_block) != SQLITE_OK) || (sq_prepare (plugin->dbh, "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1", &plugin->lookup_block) != SQLITE_OK) ) { LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); return GNUNET_SYSERR; } return GNUNET_OK; }
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); }
/** * Start a peer with the given configuration * @param tth the testing handle * @param cfgname configuration file * @param peer_id a unique number to identify the peer * @param rec receive callback * @param nc connect callback * @param nd disconnect callback * @param start_cb start callback * @param cb_cls closure for callback * @return the peer context */ struct PeerContext * GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth, const char *cfgname, int peer_id, GNUNET_TRANSPORT_ReceiveCallback rec, GNUNET_TRANSPORT_NotifyConnect nc, GNUNET_TRANSPORT_NotifyDisconnect nd, GNUNET_TRANSPORT_TESTING_start_cb start_cb, void *cb_cls) { char *emsg = NULL; struct GNUNET_PeerIdentity *dummy; GNUNET_assert (NULL != tth); GNUNET_assert (NULL != tth->tl_system); if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", "File not found: `%s' \n", cfgname); return NULL; } struct PeerContext *p = GNUNET_new (struct PeerContext); GNUNET_CONTAINER_DLL_insert (tth->p_head, tth->p_tail, p); /* Create configuration and call testing lib to modify it */ p->cfg = GNUNET_CONFIGURATION_create (); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); if (GNUNET_SYSERR == GNUNET_TESTING_configuration_create (tth->tl_system, p->cfg)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", "Testing library failed to create unique configuration based on `%s'\n", cfgname); GNUNET_free (p); return NULL; } p->no = peer_id; /* Configure peer with configuration */ p->peer = GNUNET_TESTING_peer_configure (tth->tl_system, p->cfg, p->no, NULL, &emsg); if (NULL == p->peer) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", "Testing library failed to create unique configuration based on `%s': `%s'\n", cfgname, emsg); GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); GNUNET_free_non_null (emsg); return NULL; } GNUNET_free_non_null (emsg); if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", "Testing library failed to create unique configuration based on `%s'\n", cfgname); GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); return NULL; } memset(&dummy, '\0', sizeof (dummy)); GNUNET_TESTING_peer_get_identity (p->peer, &p->id); if (0 == memcmp (&dummy, &p->id, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", "Testing library failed to obtain peer identity for peer %u\n", p->no); GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); return NULL; } else { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", "Peer %u configured with identity `%s'\n", p->no, GNUNET_i2s_full (&p->id)); } p->tth = tth; p->nc = nc; p->nd = nd; p->rec = rec; p->start_cb = start_cb; if (cb_cls != NULL) p->cb_cls = cb_cls; else p->cb_cls = p; p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, p, ¬ify_receive, ¬ify_connect, ¬ify_disconnect); if (NULL == p->th) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing", "Failed to connect to transport service for peer `%s': `%s'\n", cfgname, emsg); GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); return NULL; } p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &get_hello, p); GNUNET_assert (p->ghh != NULL); return p; }
/** * Create a new private key by reading it from a file. If the * files does not exist, create a new key and write it to the * file. Caller must free return value. Note that this function * can not guarantee that another process might not be trying * the same operation on the same file at the same time. * If the contents of the file * are invalid the old file is deleted and a fresh key is * created. * * @param filename name of file to use to store the key * @return new private key, NULL on error (for example, * permission denied) */ struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename) { struct GNUNET_CRYPTO_EddsaPrivateKey *priv; struct GNUNET_DISK_FileHandle *fd; unsigned int cnt; int ec; uint64_t fs; if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) return NULL; while (GNUNET_YES != GNUNET_DISK_file_test (filename)) { fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == fd) { if (EEXIST == errno) { if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { /* must exist but not be accessible, fail for good! */ if (0 != ACCESS (filename, R_OK)) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename); else GNUNET_break (0); /* what is going on!? */ return NULL; } continue; } LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); return NULL; } cnt = 0; while (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), GNUNET_YES)) { short_wait (); if (0 == ++cnt % 10) { ec = errno; LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not acquire lock on file `%s': %s...\n"), filename, STRERROR (ec)); } } LOG (GNUNET_ERROR_TYPE_INFO, _("Creating a new private key. This may take a while.\n")); priv = GNUNET_CRYPTO_eddsa_key_create (); GNUNET_assert (NULL != priv); GNUNET_assert (sizeof (*priv) == GNUNET_DISK_file_write (fd, priv, sizeof (*priv))); GNUNET_DISK_file_sync (fd); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); return priv; } /* key file exists already, read it! */ fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); if (NULL == fd) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); return NULL; } cnt = 0; while (1) { if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), GNUNET_NO)) { if (0 == ++cnt % 60) { ec = errno; LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not acquire lock on file `%s': %s...\n"), filename, STRERROR (ec)); LOG (GNUNET_ERROR_TYPE_ERROR, _ ("This may be ok if someone is currently generating a private key.\n")); } short_wait (); continue; } if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { /* eh, what!? File we opened is now gone!? */ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); return NULL; } if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) { /* maybe we got the read lock before the key generating * process had a chance to get the write lock; give it up! */ if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); if (0 == ++cnt % 10) { LOG (GNUNET_ERROR_TYPE_ERROR, _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"), filename, (unsigned int) fs, (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); LOG (GNUNET_ERROR_TYPE_ERROR, _("This may be ok if someone is currently generating a key.\n")); } short_wait (); /* wait a bit longer! */ continue; } break; } fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey); priv = GNUNET_malloc (fs); GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs)); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); return priv; }
/** * Load a bloom-filter from a file. * * @param filename the name of the file (or the prefix) * @param size the size of the bloom-filter (number of * bytes of storage space to use); will be rounded up * to next power of 2 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per * element (number of bits set per element in the set) * @return the bloomfilter */ struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size, unsigned int k) { struct GNUNET_CONTAINER_BloomFilter *bf; char *rbuff; OFF_T pos; int i; size_t ui; OFF_T fsize; int must_read; GNUNET_assert (NULL != filename); if ((k == 0) || (size == 0)) return NULL; if (size < BUFFSIZE) size = BUFFSIZE; ui = 1; while ( (ui < size) && (ui * 2 > ui) ) ui *= 2; size = ui; /* make sure it's a power of 2 */ bf = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_BloomFilter)); /* Try to open a bloomfilter file */ if (GNUNET_YES == GNUNET_DISK_file_test (filename)) bf->fh = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL != bf->fh) { /* file existed, try to read it! */ must_read = GNUNET_YES; if (GNUNET_OK != GNUNET_DISK_file_handle_size (bf->fh, &fsize)) { GNUNET_DISK_file_close (bf->fh); GNUNET_free (bf); return NULL; } if (fsize == 0) { /* found existing empty file, just overwrite */ if (GNUNET_OK != make_empty_file (bf->fh, size * 4LL)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); GNUNET_DISK_file_close (bf->fh); GNUNET_free (bf); return NULL; } } else if (fsize != size * 4LL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Size of file on disk is incorrect for this Bloom filter (want %llu, have %llu)\n"), (unsigned long long) (size * 4LL), (unsigned long long) fsize); GNUNET_DISK_file_close (bf->fh); GNUNET_free (bf); return NULL; } } else { /* file did not exist, don't read, just create */ must_read = GNUNET_NO; bf->fh = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == bf->fh) { GNUNET_free (bf); return NULL; } if (GNUNET_OK != make_empty_file (bf->fh, size * 4LL)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); GNUNET_DISK_file_close (bf->fh); GNUNET_free (bf); return NULL; } } bf->filename = GNUNET_strdup (filename); /* Alloc block */ bf->bitArray = GNUNET_malloc_large (size); if (bf->bitArray == NULL) { if (bf->fh != NULL) GNUNET_DISK_file_close (bf->fh); GNUNET_free (bf->filename); GNUNET_free (bf); return NULL; } bf->bitArraySize = size; bf->addressesPerElement = k; if (GNUNET_YES != must_read) return bf; /* already done! */ /* Read from the file what bits we can */ rbuff = GNUNET_malloc (BUFFSIZE); pos = 0; while (pos < size * 8LL) { int res; res = GNUNET_DISK_file_read (bf->fh, rbuff, BUFFSIZE); if (res == -1) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "read", bf->filename); GNUNET_free (rbuff); GNUNET_free (bf->filename); GNUNET_DISK_file_close (bf->fh); GNUNET_free (bf); return NULL; } if (res == 0) break; /* is ok! we just did not use that many bits yet */ for (i = 0; i < res; i++) { if ((rbuff[i] & 0x0F) != 0) setBit (bf->bitArray, pos + i * 2); if ((rbuff[i] & 0xF0) != 0) setBit (bf->bitArray, pos + i * 2 + 1); } if (res < BUFFSIZE) break; pos += BUFFSIZE * 2; /* 2 bits per byte in the buffer */ } GNUNET_free (rbuff); return bf; }
/** * Try to read the HELLOs in the given filename and discard expired * addresses. Removes the file if one the HELLO is malformed. If all * addresses are expired, the HELLO is also removed (but the HELLO * with the public key is still returned if it was found and valid). * The file can contain multiple HELLO messages. * * @param fn name of the file * @param unlink_garbage if #GNUNET_YES, try to remove useless files * @param r ReadHostFileContext to store the resutl */ static void read_host_file (const char *fn, int unlink_garbage, struct ReadHostFileContext *r) { char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; unsigned int size_total; struct GNUNET_TIME_Absolute now; unsigned int left; const struct GNUNET_HELLO_Message *hello; struct GNUNET_HELLO_Message *hello_clean; unsigned read_pos; int size_hello; r->friend_only_hello = NULL; r->hello = NULL; if (GNUNET_YES != GNUNET_DISK_file_test (fn)) return; size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes from `%s'\n", size_total, fn); if (size_total < sizeof (struct GNUNET_MessageHeader)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse HELLO in file `%s': %s\n"), fn, "Fail has invalid size"); if ( (GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn)) && (ENOENT != errno) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); return; } read_pos = 0; while (read_pos < size_total) { hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos]; size_hello = GNUNET_HELLO_size (hello); if ( (0 == size_hello) || (size_total - read_pos < size_hello) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse HELLO in file `%s'\n"), fn); if (0 == read_pos) { if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn)) && (ENOENT != errno) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); } else { if ((GNUNET_YES == unlink_garbage) && (0 != TRUNCATE (fn, read_pos)) && (ENOENT != errno) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "truncate", fn); } return; } now = GNUNET_TIME_absolute_get (); hello_clean = GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, &now); if (NULL == hello_clean) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse HELLO in file `%s'\n"), fn); if ((GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn)) && (ENOENT != errno) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); return; } left = 0; (void) GNUNET_HELLO_iterate_addresses (hello_clean, GNUNET_NO, &count_addresses, &left); if (0 == left) { GNUNET_free (hello_clean); break; } if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean)) { if (NULL == r->hello) r->hello = hello_clean; else { GNUNET_break (0); GNUNET_free (r->hello); r->hello = hello_clean; } } else { if (NULL == r->friend_only_hello) r->friend_only_hello = hello_clean; else { GNUNET_break (0); GNUNET_free (r->friend_only_hello); r->friend_only_hello = hello_clean; } } read_pos += size_hello; } if (0 == left) { /* no addresses left, remove from disk */ if ( (GNUNET_YES == unlink_garbage) && (0 != UNLINK (fn)) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' and `%s' HELLO message in file\n", (NULL != r->hello) ? "public" : "NON-public", (NULL != r->friend_only_hello) ? "friend only" : "NO friend only"); }