/** * Cancel iteration over all indexed files. * * @param gic operation to cancel */ void GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic) { GNUNET_CLIENT_disconnect (gic->client); GNUNET_free (gic); }
/** * Get namespace name, metadata and rank * This is a wrapper around internal read_info() call, and ensures that * returned data is not invalid (not NULL). * * @param cfg configuration * @param nsid cryptographic ID of the namespace * @param ret_meta a location to store metadata pointer. NULL, if metadata * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). * @param ret_rank a location to store rank. NULL, if rank not needed. * @param ret_name a location to store human-readable name. Name is not unique. * NULL, if name is not needed. Free with GNUNET_free(). * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with * a duplicate of a "no-name" placeholder * @return GNUNET_OK on success. GNUENT_SYSERR if the data was * unobtainable (in that case ret_* are filled with placeholders - * empty metadata container, rank -1 and a "no-name" name). */ int GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, int32_t *ret_rank, char **ret_name, int *name_is_a_dup) { struct GNUNET_CONTAINER_MetaData *meta; char *name; int32_t rank = -1; meta = NULL; name = NULL; if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name)) { if ((meta != NULL) && (name == NULL)) name = GNUNET_CONTAINER_meta_data_get_first_by_types (meta, EXTRACTOR_METATYPE_TITLE, EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, EXTRACTOR_METATYPE_FILENAME, EXTRACTOR_METATYPE_DESCRIPTION, EXTRACTOR_METATYPE_SUBJECT, EXTRACTOR_METATYPE_PUBLISHER, EXTRACTOR_METATYPE_AUTHOR_NAME, EXTRACTOR_METATYPE_COMMENT, EXTRACTOR_METATYPE_SUMMARY, -1); if (ret_name != NULL) { if (name == NULL) { name = GNUNET_strdup (_("no-name")); if (name_is_a_dup != NULL) *name_is_a_dup = GNUNET_YES; } else if (name_is_a_dup != NULL) *name_is_a_dup = GNUNET_NO; *ret_name = name; } else if (name != NULL) GNUNET_free (name); if (ret_meta != NULL) { if (meta == NULL) meta = GNUNET_CONTAINER_meta_data_create (); *ret_meta = meta; } else if (meta != NULL) GNUNET_CONTAINER_meta_data_destroy (meta); if (ret_rank != NULL) *ret_rank = rank; return GNUNET_OK; } if (ret_name != NULL) *ret_name = GNUNET_strdup (_("no-name")); if (ret_meta != NULL) *ret_meta = GNUNET_CONTAINER_meta_data_create (); if (ret_rank != NULL) *ret_rank = -1; if (name_is_a_dup != NULL) *name_is_a_dup = GNUNET_YES; return GNUNET_SYSERR; }
static void end (void *cls) { if (NULL != zi) { GNUNET_NAMESTORE_zone_iteration_stop (zi); zi = NULL; } if (endbadly_task != NULL) { GNUNET_SCHEDULER_cancel (endbadly_task); endbadly_task = NULL; } if (privkey != NULL) GNUNET_free (privkey); privkey = NULL; if (privkey2 != NULL) GNUNET_free (privkey2); privkey2 = NULL; GNUNET_free (s_name_1); GNUNET_free (s_name_2); GNUNET_free (s_name_3); if (s_rd_1 != NULL) { GNUNET_free ((void *)s_rd_1->data); GNUNET_free (s_rd_1); } if (s_rd_2 != NULL) { GNUNET_free ((void *)s_rd_2->data); GNUNET_free (s_rd_2); } if (s_rd_3 != NULL) { GNUNET_free ((void *)s_rd_3->data); GNUNET_free (s_rd_3); } if (nsh != NULL) GNUNET_NAMESTORE_disconnect (nsh); nsh = NULL; }
/** * 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; }
/** * Convert human-readable version of a 'value' of a record to the binary * representation. * * @param type type of the record * @param s human-readable string * @param data set to value in binary encoding (will be allocated) * @param data_size set to number of bytes in data * @return GNUNET_OK on success */ int GNUNET_NAMESTORE_string_to_value (uint32_t type, const char *s, void **data, size_t *data_size) { struct in_addr value_a; struct in6_addr value_aaaa; struct GNUNET_CRYPTO_ShortHashCode pkey; struct soa_data *soa; struct vpn_data *vpn; struct tlsa_data *tlsa; char result[253 + 1]; char soa_rname[253 + 1]; char soa_mname[253 + 1]; char s_peer[103 + 1]; char s_serv[253 + 1]; unsigned int soa_serial; unsigned int soa_refresh; unsigned int soa_retry; unsigned int soa_expire; unsigned int soa_min; uint16_t mx_pref; uint16_t mx_pref_n; unsigned int proto; switch (type) { case 0: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unsupported record type %d\n"), (int) type); return GNUNET_SYSERR; case GNUNET_DNSPARSER_TYPE_A: if (1 != inet_pton (AF_INET, s, &value_a)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse IPv4 address `%s'\n"), s); return GNUNET_SYSERR; } *data = GNUNET_malloc (sizeof (struct in_addr)); memcpy (*data, &value_a, sizeof (value_a)); *data_size = sizeof (value_a); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_NS: *data = GNUNET_strdup (s); *data_size = strlen (s) + 1; return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_CNAME: *data = GNUNET_strdup (s); *data_size = strlen (s) + 1; return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_SOA: if (7 != SSCANF (s, "rname=%253s mname=%253s %u,%u,%u,%u,%u", soa_rname, soa_mname, &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse SOA record `%s'\n"), s); return GNUNET_SYSERR; } *data_size = sizeof (struct soa_data)+strlen(soa_rname)+strlen(soa_mname)+2; *data = GNUNET_malloc (*data_size); soa = (struct soa_data*)*data; soa->serial = htonl(soa_serial); soa->refresh = htonl(soa_refresh); soa->retry = htonl(soa_retry); soa->expire = htonl(soa_expire); soa->minimum = htonl(soa_min); strcpy((char*)&soa[1], soa_rname); strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_PTR: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_MX: if (2 != SSCANF(s, "%hu,%253s", &mx_pref, result)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse MX record `%s'\n"), s); return GNUNET_SYSERR; } *data_size = sizeof (uint16_t)+strlen(result)+1; *data = GNUNET_malloc (*data_size); mx_pref_n = htons(mx_pref); memcpy(*data, &mx_pref_n, sizeof (uint16_t)); strcpy((*data)+sizeof (uint16_t), result); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_TXT: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_AAAA: if (1 != inet_pton (AF_INET6, s, &value_aaaa)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse IPv6 address `%s'\n"), s); return GNUNET_SYSERR; } *data = GNUNET_malloc (sizeof (struct in6_addr)); *data_size = sizeof (struct in6_addr); memcpy (*data, &value_aaaa, sizeof (value_aaaa)); return GNUNET_OK; case GNUNET_NAMESTORE_TYPE_PKEY: if (GNUNET_OK != GNUNET_CRYPTO_short_hash_from_string (s, &pkey)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse PKEY record `%s'\n"), s); return GNUNET_SYSERR; } *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode)); memcpy (*data, &pkey, sizeof (pkey)); *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); return GNUNET_OK; case GNUNET_NAMESTORE_TYPE_PSEU: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_NAMESTORE_TYPE_LEHO: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_NAMESTORE_TYPE_VPN: if (3 != SSCANF (s,"%u %103s %253s", &proto, s_peer, s_serv)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse VPN record string `%s'\n"), s); return GNUNET_SYSERR; } *data_size = sizeof (struct vpn_data) + strlen (s_serv) + 1; *data = vpn = GNUNET_malloc (*data_size); if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, &vpn->peer)) { GNUNET_free (vpn); *data_size = 0; return GNUNET_SYSERR; } vpn->proto = htons ((uint16_t) proto); strcpy ((char*)&vpn[1], s_serv); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_TLSA: *data_size = sizeof (struct tlsa_data) + strlen (s) - 6; *data = tlsa = GNUNET_malloc (*data_size); if (4 != SSCANF (s, "%c %c %c %s", &tlsa->usage, &tlsa->selector, &tlsa->matching_type, (char*)&tlsa[1])) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse TLSA record string `%s'\n"), s); *data_size = 0; GNUNET_free (tlsa); return GNUNET_SYSERR; } return GNUNET_OK; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unsupported record type %d\n"), (int) type); return GNUNET_SYSERR; } }
/** * Function called when we receive a message from the VPN service. * * @param cls the 'struct GNUNET_VPN_Handle' * @param msg message received, NULL on timeout or fatal error */ static void receive_response (void *cls, const struct GNUNET_MessageHeader* msg) { struct GNUNET_VPN_Handle *vh = cls; const struct RedirectToIpResponseMessage *rm; struct GNUNET_VPN_RedirectionRequest *rr; size_t msize; size_t alen; int af; if (NULL == msg) { reconnect (vh); return; } if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP) || (sizeof (struct RedirectToIpResponseMessage) > (msize = ntohs (msg->size))) ) { GNUNET_break (0); reconnect (vh); return; } rm = (const struct RedirectToIpResponseMessage *) msg; af = (int) ntohl (rm->result_af); switch (af) { case AF_UNSPEC: alen = 0; break; case AF_INET: alen = sizeof (struct in_addr); break; case AF_INET6: alen = sizeof (struct in6_addr); break; default: GNUNET_break (0); reconnect (vh); return; } if ( (msize != alen + sizeof (struct RedirectToIpResponseMessage)) || (0 == rm->request_id) ) { GNUNET_break (0); reconnect (vh); return; } GNUNET_CLIENT_receive (vh->client, &receive_response, vh, GNUNET_TIME_UNIT_FOREVER_REL); for (rr = vh->rr_head; NULL != rr; rr = rr->next) { if (rr->request_id == rm->request_id) { GNUNET_CONTAINER_DLL_remove (vh->rr_head, vh->rr_tail, rr); rr->cb (rr->cb_cls, af, (af == AF_UNSPEC) ? NULL : &rm[1]); GNUNET_free (rr); break; } } }
void GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l, char *experiment_name, int plots) { struct GNUNET_DISK_FileHandle *f[l->num_slaves]; struct GNUNET_DISK_FileHandle *f_m; char *tmp_exp_name; char *filename_master; char *filename_slaves[l->num_slaves]; char *data; struct PeerLoggingTimestep *cur_lt; struct PartnerLoggingTimestep *plt; struct GNUNET_TIME_Absolute timestamp; int c_m; int c_s; timestamp = GNUNET_TIME_absolute_get(); tmp_exp_name = experiment_name; for (c_m = 0; c_m < l->num_masters; c_m++) { GNUNET_asprintf (&filename_master, "%s_%llu_master%u_%s", experiment_name, timestamp.abs_value_us, c_m, l->name); fprintf (stderr, "Writing data for master %u to file `%s'\n", c_m,filename_master); f_m = GNUNET_DISK_file_open (filename_master, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f_m) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_master); GNUNET_free (filename_master); return; } GNUNET_asprintf (&data, "# master %u; experiment : %s\n" "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; \n" , c_m, experiment_name); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n",filename_master); GNUNET_free (data); for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { GNUNET_asprintf (&filename_slaves[c_s], "%s_%llu_master%u_slave_%u_%s", tmp_exp_name, timestamp.abs_value_us, c_m, c_s, l->name); fprintf (stderr, "Writing data for master %u slave %u to file `%s'\n", c_m, c_s, filename_slaves[c_s]); f[c_s] = GNUNET_DISK_file_open (filename_slaves[c_s], GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f[c_s]) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_slaves[c_s]); GNUNET_free (filename_slaves[c_s]); return; } /* Header */ GNUNET_asprintf (&data, "# master %u; slave %u ; experiment : %s\n" "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; " \ "rtt; bw in; bw out; ats_cost_lan; ats_cost_wlan; ats_delay; ats_distance; ats_network_type; ats_utilization_up ;ats_utilization_down;" \ "pref bandwidth; pref delay\n", c_m, c_s, experiment_name); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n",filename_slaves[c_s]); GNUNET_free (data); } for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next) { if (l->verbose) fprintf (stderr, "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n", l->lp[c_m].peer->no, (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000, cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send, cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv); /* Assembling master string */ GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;\n", (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000, cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send, cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to master file %u\n", c_m); GNUNET_free (data); for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { plt = &cur_lt->slaves_log[c_s]; /* Log partners */ /* Assembling slave string */ GNUNET_asprintf(&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%u;%u;%u;%.3f;%.3f\n", (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000, plt->total_messages_sent, plt->total_bytes_sent, plt->throughput_sent, plt->total_messages_received, plt->total_bytes_received, plt->throughput_recv, (double) plt->app_rtt / 1000, plt->bandwidth_in, plt->bandwidth_out, plt->ats_cost_lan, plt->ats_cost_wan, plt->ats_cost_wlan, plt->ats_delay, plt->ats_distance, plt->ats_network_type, plt->ats_utilization_up, plt->ats_utilization_down, plt->pref_bandwidth, plt->pref_delay); if (l->verbose) fprintf (stderr, "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %u bw_in %u bw_out %u \n", plt->slave->no, plt->total_messages_sent, plt->total_bytes_sent, plt->throughput_sent, plt->total_messages_received, plt->total_bytes_received, plt->throughput_recv, plt->app_rtt, plt->ats_delay, plt->bandwidth_in, plt->bandwidth_out); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n", filename_slaves[c_s]); GNUNET_free (data); } } for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { if (GNUNET_SYSERR == GNUNET_DISK_file_close(f[c_s])) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close log file for master[%u] slave[%u]\n", c_m, c_s); return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data file successfully written to log file for `%s'\n", filename_slaves[c_s]); } if (GNUNET_SYSERR == GNUNET_DISK_file_close(f_m)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close log file `%s'\n", filename_master); return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data file successfully written to log file for master `%s'\n", filename_master); if (GNUNET_YES == plots) { write_throughput_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves); write_rtt_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves); write_bw_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves); } } }
/** * Solves the MLP problem * * @param mlp the MLP Handle * @param ctx solution context * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx) { int res; /* Check if solving is already running */ if (GNUNET_YES == mlp->semaphore) { if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel(mlp->mlp_task); mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; } mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp); return GNUNET_SYSERR; } mlp->semaphore = GNUNET_YES; mlp->last_execution = GNUNET_TIME_absolute_get (); ctx->lp_result = GNUNET_SYSERR; ctx->mlp_result = GNUNET_SYSERR; ctx->lp_duration = GNUNET_TIME_UNIT_FOREVER_REL; ctx->mlp_duration = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve LP problem\n"); #if WRITE_MLP char * name; static int i; i++; GNUNET_asprintf(&name, "problem_%i", i); glp_write_lp (mlp->prob, 0, name); GNUNET_free (name); # endif res = mlp_solve_lp_problem (mlp, ctx); ctx->lp_result = res; if (res != GNUNET_OK) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "LP Problem solving failed\n"); mlp->semaphore = GNUNET_NO; return GNUNET_SYSERR; } #if WRITE_MLP GNUNET_asprintf(&name, "problem_%i_lp_solution", i); glp_print_sol (mlp->prob, name); GNUNET_free (name); # endif GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve MLP problem\n"); res = mlp_solve_mlp_problem (mlp, ctx); ctx->mlp_result = res; if (res != GNUNET_OK) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP Problem solving failed\n"); mlp->semaphore = GNUNET_NO; return GNUNET_SYSERR; } #if WRITE_MLP GNUNET_asprintf(&name, "problem_%i_mlp_solution", i); glp_print_mip (mlp->prob, name); GNUNET_free (name); # endif GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved %s (LP duration %llu / MLP duration %llu)\n", (GNUNET_OK == res) ? "successfully" : "failed", ctx->lp_duration.rel_value, ctx->mlp_duration.rel_value); /* Process result */ struct ATS_Peer *p = NULL; struct ATS_Address *a = NULL; struct MLP_information *mlpi = NULL; for (p = mlp->peer_head; p != NULL; p = p->next) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s'\n", GNUNET_i2s (&p->id)); for (a = p->head; a != NULL; a = a->next) { double b = 0.0; double n = 0.0; mlpi = a->mlp_information; b = glp_mip_col_val(mlp->prob, mlpi->c_b); mlpi->b = b; n = glp_mip_col_val(mlp->prob, mlpi->c_n); if (n == 1.0) mlpi->n = GNUNET_YES; else mlpi->n = GNUNET_NO; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tAddress %s %f\n", (n == 1.0) ? "[x]" : "[ ]", b); } } if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel(mlp->mlp_task); mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; } mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp); mlp->semaphore = GNUNET_NO; return res; }
/** * Init the MLP problem solving component * * @param cfg the GNUNET_CONFIGURATION_Handle handle * @param stats the GNUNET_STATISTICS handle * @param max_duration maximum numbers of iterations for the LP/MLP Solver * @param max_iterations maximum time limit for the LP/MLP Solver * @return struct GAS_MLP_Handle * on success, NULL on fail */ struct GAS_MLP_Handle * GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_STATISTICS_Handle *stats, struct GNUNET_TIME_Relative max_duration, unsigned int max_iterations) { struct GAS_MLP_Handle * mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle)); double D; double R; double U; unsigned long long tmp; unsigned int b_min; unsigned int n_min; struct GNUNET_TIME_Relative i_exec; int c; char * quota_out_str; char * quota_in_str; /* Init GLPK environment */ int res = glp_init_env(); switch (res) { case 0: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", "initialization successful"); break; case 1: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", "environment is already initialized"); break; case 2: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", "initialization failed (insufficient memory)"); GNUNET_free(mlp); return NULL; break; case 3: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", "initialization failed (unsupported programming model)"); GNUNET_free(mlp); return NULL; break; default: break; } /* Create initial MLP problem */ mlp->prob = glp_create_prob(); GNUNET_assert (mlp->prob != NULL); mlp->BIG_M = (double) BIG_M_VALUE; /* Get diversity coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_D", &tmp)) D = (double) tmp / 100; else D = 1.0; /* Get proportionality coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_R", &tmp)) R = (double) tmp / 100; else R = 1.0; /* Get utilization coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_U", &tmp)) U = (double) tmp / 100; else U = 1.0; /* Get quality metric coefficients from configuration */ int i_delay = -1; int i_distance = -1; int q[GNUNET_ATS_QualityPropertiesCount] = GNUNET_ATS_QualityProperties; for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) { /* initialize quality coefficients with default value 1.0 */ mlp->co_Q[c] = 1.0; mlp->q[c] = q[c]; if (q[c] == GNUNET_ATS_QUALITY_NET_DELAY) i_delay = c; if (q[c] == GNUNET_ATS_QUALITY_NET_DISTANCE) i_distance = c; } if ((i_delay != -1) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_QUALITY_DELAY", &tmp))) mlp->co_Q[i_delay] = (double) tmp / 100; else mlp->co_Q[i_delay] = 1.0; if ((i_distance != -1) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "COEFFICIENT_QUALITY_DISTANCE", &tmp))) mlp->co_Q[i_distance] = (double) tmp / 100; else mlp->co_Q[i_distance] = 1.0; /* Get minimum bandwidth per used address from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "MIN_BANDWIDTH", &tmp)) b_min = tmp; else { b_min = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); } /* Get minimum number of connections from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", "MIN_CONNECTIONS", &tmp)) n_min = tmp; else n_min = 4; /* Init network quotas */ int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType; for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) { mlp->quota_index[c] = quotas[c]; static char * entry_in = NULL; static char * entry_out = NULL; unsigned long long quota_in = 0; unsigned long long quota_out = 0; switch (quotas[c]) { case GNUNET_ATS_NET_UNSPECIFIED: entry_out = "UNSPECIFIED_QUOTA_OUT"; entry_in = "UNSPECIFIED_QUOTA_IN"; break; case GNUNET_ATS_NET_LOOPBACK: entry_out = "LOOPBACK_QUOTA_OUT"; entry_in = "LOOPBACK_QUOTA_IN"; break; case GNUNET_ATS_NET_LAN: entry_out = "LAN_QUOTA_OUT"; entry_in = "LAN_QUOTA_IN"; break; case GNUNET_ATS_NET_WAN: entry_out = "WAN_QUOTA_OUT"; entry_in = "WAN_QUOTA_IN"; break; case GNUNET_ATS_NET_WLAN: entry_out = "WLAN_QUOTA_OUT"; entry_in = "WLAN_QUOTA_IN"; break; default: break; } if ((entry_in == NULL) || (entry_out == NULL)) continue; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str)) { if (0 == strcmp(quota_out_str, BIG_M_STRING) || (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, "a_out))) quota_out = mlp->BIG_M; GNUNET_free (quota_out_str); quota_out_str = NULL; } else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) { quota_out = mlp->BIG_M; } else { quota_out = mlp->BIG_M; } if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str)) { if (0 == strcmp(quota_in_str, BIG_M_STRING) || (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, "a_in))) quota_in = mlp->BIG_M; GNUNET_free (quota_in_str); quota_in_str = NULL; } else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) { quota_in = mlp->BIG_M; } else { quota_in = mlp->BIG_M; } /* Check if defined quota could make problem unsolvable */ if (((n_min * b_min) > quota_out) && (GNUNET_ATS_NET_UNSPECIFIED != quotas[c])) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min); GAS_mlp_done(mlp); mlp = NULL; return NULL; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n", entry_out, quota_out, entry_in, quota_in); GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_out, quota_out, GNUNET_NO); GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_in, quota_in, GNUNET_NO); mlp->quota_out[c] = quota_out; mlp->quota_in[c] = quota_in; } /* Get minimum number of connections from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg, "ats", "ATS_EXEC_INTERVAL", &i_exec)) mlp->exec_interval = i_exec; else mlp->exec_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30); mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats; mlp->max_iterations = max_iterations; mlp->max_exec_duration = max_duration; mlp->auto_solve = GNUNET_YES; /* Redirect GLPK output to GNUnet logging */ glp_error_hook((void *) mlp, &mlp_term_hook); /* Init LP solving parameters */ glp_init_smcp(&mlp->control_param_lp); mlp->control_param_lp.msg_lev = GLP_MSG_OFF; #if VERBOSE_GLPK mlp->control_param_lp.msg_lev = GLP_MSG_ALL; #endif mlp->control_param_lp.it_lim = max_iterations; mlp->control_param_lp.tm_lim = max_duration.rel_value; /* Init MLP solving parameters */ glp_init_iocp(&mlp->control_param_mlp); mlp->control_param_mlp.msg_lev = GLP_MSG_OFF; #if VERBOSE_GLPK mlp->control_param_mlp.msg_lev = GLP_MSG_ALL; #endif mlp->control_param_mlp.tm_lim = max_duration.rel_value; mlp->last_execution = GNUNET_TIME_UNIT_FOREVER_ABS; mlp->co_D = D; mlp->co_R = R; mlp->co_U = U; mlp->b_min = b_min; mlp->n_min = n_min; mlp->m_q = GNUNET_ATS_QualityPropertiesCount; mlp->semaphore = GNUNET_NO; return mlp; }
/** * Iterate over all entries in a directory. Note that directories * are structured such that it is possible to iterate over the * individual blocks as well as over the entire directory. Thus * a client can call this function on the buffer in the * GNUNET_FS_ProgressCallback. Also, directories can optionally * include the contents of (small) files embedded in the directory * itself; for those files, the processor may be given the * contents of the file directly by this function. * <p> * * Note that this function maybe called on parts of directories. Thus * parser errors should not be reported _at all_ (with GNUNET_break). * Still, if some entries can be recovered despite these parsing * errors, the function should try to do this. * * @param size number of bytes in data * @param data pointer to the beginning of the directory * @param offset offset of data in the directory * @param dep function to call on each entry * @param dep_cls closure for dep * @return GNUNET_OK if this could be a block in a directory, * GNUNET_NO if this could be part of a directory (but not 100% OK) * GNUNET_SYSERR if 'data' does not represent a directory */ int GNUNET_FS_directory_list_contents (size_t size, const void *data, uint64_t offset, GNUNET_FS_DirectoryEntryProcessor dep, void *dep_cls) { struct GetFullDataClosure full_data; const char *cdata = data; char *emsg; uint64_t pos; uint64_t align; uint32_t mdSize; uint64_t epos; struct GNUNET_FS_Uri *uri; struct GNUNET_CONTAINER_MetaData *md; char *filename; if ((offset == 0) && ((size < 8 + sizeof (uint32_t)) || (0 != memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8)))) return GNUNET_SYSERR; pos = offset; if (offset == 0) { GNUNET_memcpy (&mdSize, &cdata[8], sizeof (uint32_t)); mdSize = ntohl (mdSize); if (mdSize > size - 8 - sizeof (uint32_t)) { /* invalid size */ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("MAGIC mismatch. This is not a GNUnet directory.\n")); return GNUNET_SYSERR; } md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + sizeof (uint32_t)], mdSize); if (md == NULL) { GNUNET_break (0); return GNUNET_SYSERR; /* malformed ! */ } dep (dep_cls, NULL, NULL, md, 0, NULL); GNUNET_CONTAINER_meta_data_destroy (md); pos = 8 + sizeof (uint32_t) + mdSize; } while (pos < size) { /* find end of URI */ if (cdata[pos] == '\0') { /* URI is never empty, must be end of block, * skip to next alignment */ align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE; if (align == pos) { /* if we were already aligned, still skip a block! */ align += DBLOCK_SIZE; } pos = align; if (pos >= size) { /* malformed - or partial download... */ break; } } epos = pos; while ((epos < size) && (cdata[epos] != '\0')) epos++; if (epos >= size) return GNUNET_NO; /* malformed - or partial download */ uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg); pos = epos + 1; if (uri == NULL) { GNUNET_free (emsg); pos--; /* go back to '\0' to force going to next alignment */ continue; } if (GNUNET_FS_uri_test_ksk (uri)) { GNUNET_FS_uri_destroy (uri); GNUNET_break (0); return GNUNET_NO; /* illegal in directory! */ } GNUNET_memcpy (&mdSize, &cdata[pos], sizeof (uint32_t)); mdSize = ntohl (mdSize); pos += sizeof (uint32_t); if (pos + mdSize > size) { GNUNET_FS_uri_destroy (uri); return GNUNET_NO; /* malformed - or partial download */ } md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize); if (md == NULL) { GNUNET_FS_uri_destroy (uri); GNUNET_break (0); return GNUNET_NO; /* malformed ! */ } pos += mdSize; filename = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); full_data.size = 0; full_data.data = NULL; GNUNET_CONTAINER_meta_data_iterate (md, &find_full_data, &full_data); if (dep != NULL) { dep (dep_cls, filename, uri, md, full_data.size, full_data.data); } GNUNET_free_non_null (full_data.data); GNUNET_free_non_null (filename); GNUNET_CONTAINER_meta_data_destroy (md); GNUNET_FS_uri_destroy (uri); } return GNUNET_OK; }
/** * Notify the plan about a peer being no longer available; * destroy all entries associated with this peer. * * @param cp connected peer */ void GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp) { const struct GNUNET_PeerIdentity *id; struct PeerPlan *pp; struct GSF_RequestPlan *rp; struct GSF_PendingRequestData *prd; struct GSF_PendingRequestPlanBijection *bi; id = GSF_connected_peer_get_identity2_ (cp); pp = GNUNET_CONTAINER_multihashmap_get (plans, &id->hashPubKey); if (NULL == pp) return; /* nothing was ever planned for this peer */ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (plans, &id->hashPubKey, pp)); if (NULL != pp->pth) { GSF_peer_transmit_cancel_ (pp->pth); pp->pth = NULL; } if (GNUNET_SCHEDULER_NO_TASK != pp->task) { GNUNET_SCHEDULER_cancel (pp->task); pp->task = GNUNET_SCHEDULER_NO_TASK; } while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->priority_heap))) { GNUNET_break (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (pp->plan_map, get_rp_key (rp), rp)); while (NULL != (bi = rp->pe_head)) { GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi); prd = GSF_pending_request_get_data_ (bi->pr); GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi); GNUNET_free (bi); } plan_count--; GNUNET_free (rp); } GNUNET_CONTAINER_heap_destroy (pp->priority_heap); while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->delay_heap))) { GNUNET_break (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (pp->plan_map, get_rp_key (rp), rp)); while (NULL != (bi = rp->pe_head)) { prd = GSF_pending_request_get_data_ (bi->pr); GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi); GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi); GNUNET_free (bi); } plan_count--; GNUNET_free (rp); } GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# query plan entries"), plan_count, GNUNET_NO); GNUNET_CONTAINER_heap_destroy (pp->delay_heap); GNUNET_CONTAINER_multihashmap_destroy (pp->plan_map); GNUNET_free (pp); }
/** * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages * * @param cls identification of the client * @param msg the actual message */ void handle_peer_create (void *cls, const struct GNUNET_TESTBED_PeerCreateMessage *msg) { struct GNUNET_SERVICE_Client *client = cls; struct GNUNET_MQ_Envelope *env; struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply; struct GNUNET_CONFIGURATION_Handle *cfg; struct ForwardedOperationContext *fo_ctxt; struct Route *route; struct Peer *peer; char *emsg; uint32_t host_id; uint32_t peer_id; host_id = ntohl (msg->host_id); peer_id = ntohl (msg->peer_id); if (VALID_PEER_ID (peer_id)) { (void) GNUNET_asprintf (&emsg, "Peer with ID %u already exists", peer_id); GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), emsg); GNUNET_free (emsg); GNUNET_SERVICE_client_continue (client); return; } if (UINT32_MAX == peer_id) { GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), "Cannot create peer with given ID"); GNUNET_SERVICE_client_continue (client); return; } if (host_id == GST_context->host_id) { /* We are responsible for this peer */ cfg = GNUNET_TESTBED_extract_config_ (&msg->header); if (NULL == cfg) { GNUNET_break (0); GNUNET_SERVICE_client_drop (client); return; } GNUNET_CONFIGURATION_set_value_number (cfg, "TESTBED", "PEERID", (unsigned long long) peer_id); GNUNET_CONFIGURATION_set_value_number (cfg, "PATHS", "PEERID", (unsigned long long) peer_id); peer = GNUNET_new (struct Peer); peer->is_remote = GNUNET_NO; peer->details.local.cfg = cfg; peer->id = peer_id; LOG_DEBUG ("Creating peer with id: %u\n", (unsigned int) peer->id); peer->details.local.peer = GNUNET_TESTING_peer_configure (GST_context->system, peer->details.local.cfg, peer->id, NULL /* Peer id */ , &emsg); if (NULL == peer->details.local.peer) { LOG (GNUNET_ERROR_TYPE_WARNING, "Configuring peer failed: %s\n", emsg); GNUNET_free (emsg); GNUNET_free (peer); GNUNET_break (0); GNUNET_SERVICE_client_drop (client); return; } peer->details.local.is_running = GNUNET_NO; peer_list_add (peer); env = GNUNET_MQ_msg (reply, GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS); reply->peer_id = msg->peer_id; reply->operation_id = msg->operation_id; GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); GNUNET_SERVICE_client_continue (client); return; }
/** * Test if the service is running. If we are given a UNIXPATH or a local address, * we do this NOT by trying to connect to the service, but by trying to BIND to * the same port. If the BIND fails, we know the service is running. * * @param service name of the service to wait for * @param cfg configuration to use * @param timeout how long to wait at most * @param task task to run if service is running * (reason will be "PREREQ_DONE" (service running) * or "TIMEOUT" (service not known to be running)) * @param task_cls closure for task */ void GNUNET_CLIENT_service_test (const char *service, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task task, void *task_cls) { char *hostname; unsigned long long port; struct GNUNET_NETWORK_Handle *sock; struct GNUNET_CLIENT_Connection *client; LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n", service); #ifdef AF_UNIX { /* probe UNIX support */ struct sockaddr_un s_un; size_t slen; char *unixpath; unixpath = NULL; if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */ { if (strlen (unixpath) >= sizeof (s_un.sun_path)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath, (unsigned long long) sizeof (s_un.sun_path)); unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); LOG (GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); } } if (NULL != unixpath) { sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); if (NULL != sock) { memset (&s_un, 0, sizeof (s_un)); s_un.sun_family = AF_UNIX; slen = strlen (unixpath) + 1; if (slen >= sizeof (s_un.sun_path)) slen = sizeof (s_un.sun_path) - 1; memcpy (s_un.sun_path, unixpath, slen); s_un.sun_path[slen] = '\0'; slen = sizeof (struct sockaddr_un); #if LINUX s_un.sun_path[0] = '\0'; #endif #if HAVE_SOCKADDR_IN_SIN_LEN s_un.sun_len = (u_char) slen; #endif if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un, slen)) { /* failed to bind => service must be running */ GNUNET_free (unixpath); (void) GNUNET_NETWORK_socket_close (sock); GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); return; } (void) GNUNET_NETWORK_socket_close (sock); /* let's try IP */ } } GNUNET_free_non_null (unixpath); } #endif hostname = NULL; if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) || (port > 65535) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME", &hostname))) { /* UNIXPATH failed (if possible) AND IP failed => error */ service_test_error (task, task_cls); return; } if (0 == strcmp ("localhost", hostname) #if !LINUX && 0 #endif ) { /* can test using 'bind' */ struct sockaddr_in s_in; memset (&s_in, 0, sizeof (s_in)); #if HAVE_SOCKADDR_IN_SIN_LEN s_in.sin_len = sizeof (struct sockaddr_in); #endif s_in.sin_family = AF_INET; s_in.sin_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in, sizeof (s_in))) { /* failed to bind => service must be running */ GNUNET_free (hostname); (void) GNUNET_NETWORK_socket_close (sock); GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); return; } (void) GNUNET_NETWORK_socket_close (sock); } } if (0 == strcmp ("ip6-localhost", hostname) #if !LINUX && 0 #endif ) { /* can test using 'bind' */ struct sockaddr_in6 s_in6; memset (&s_in6, 0, sizeof (s_in6)); #if HAVE_SOCKADDR_IN_SIN_LEN s_in6.sin6_len = sizeof (struct sockaddr_in6); #endif s_in6.sin6_family = AF_INET6; s_in6.sin6_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6, sizeof (s_in6))) { /* failed to bind => service must be running */ GNUNET_free (hostname); (void) GNUNET_NETWORK_socket_close (sock); GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); return; } (void) GNUNET_NETWORK_socket_close (sock); } } if (((0 == strcmp ("localhost", hostname)) || (0 == strcmp ("ip6-localhost", hostname))) #if !LINUX && 0 #endif ) { /* all binds succeeded => claim service not running right now */ GNUNET_free_non_null (hostname); service_test_error (task, task_cls); return; } GNUNET_free_non_null (hostname); /* non-localhost, try 'connect' method */ client = GNUNET_CLIENT_connect (service, cfg); if (NULL == client) { LOG (GNUNET_ERROR_TYPE_INFO, _("Could not connect to service `%s', must not be running.\n"), service); service_test_error (task, task_cls); return; } client->test_cb = task; client->test_cb_cls = task_cls; client->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); if (NULL == GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), timeout, GNUNET_YES, &write_test, client)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failure to transmit request to service `%s'\n"), service); service_test_error (task, task_cls); GNUNET_CLIENT_disconnect (client); return; } }
/** * Try to connect to the service. * * @param service_name name of service to connect to * @param cfg configuration to use * @param attempt counter used to alternate between IP and UNIX domain sockets * @return NULL on error */ static struct GNUNET_CONNECTION_Handle * do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt) { struct GNUNET_CONNECTION_Handle *connection; char *hostname; unsigned long long port; connection = NULL; if (0 == (attempt % 2)) { /* on even rounds, try UNIX first */ connection = try_unixpath (service_name, cfg); if (NULL != connection) return connection; } if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) { if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) || (port > 65535) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", &hostname))) { LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Could not determine valid hostname and port for service `%s' from configuration.\n"), service_name); return NULL; } if (0 == strlen (hostname)) { GNUNET_free (hostname); LOG (GNUNET_ERROR_TYPE_WARNING, _("Need a non-empty hostname for service `%s'.\n"), service_name); return NULL; } } else { /* unspecified means 0 (disabled) */ port = 0; hostname = NULL; } if (0 == port) { /* if port is 0, try UNIX */ connection = try_unixpath (service_name, cfg); if (NULL != connection) return connection; LOG (GNUNET_ERROR_TYPE_DEBUG, "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", service_name); GNUNET_free_non_null (hostname); return NULL; } connection = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); GNUNET_free (hostname); return connection; }
static void check (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { #if !HAVE_LIBGLPK GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!"); ret = 1; return; #endif struct ATS_Address addr[10]; struct ATS_PreferedAddress *res[10]; struct MLP_information *mlpi; struct GAS_MLP_SolutionContext ctx; stats = GNUNET_STATISTICS_create("ats", cfg); addresses = GNUNET_CONTAINER_multihashmap_create (10); mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); mlp->auto_solve = GNUNET_NO; struct GNUNET_PeerIdentity p[10]; /* Creating peer 1 */ GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &p[0].hashPubKey); /* Creating peer 1 address 1 */ addr[0].peer.hashPubKey = p[0].hashPubKey; struct GNUNET_ATS_Information a1_ats[3]; set_ats (&a1_ats[0], GNUNET_ATS_QUALITY_NET_DISTANCE, 1); set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 0); set_ats (&a1_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0); create_address (&addr[0], "dummy", 3, &a1_ats[0]); addr[0].atsp_network_type = GNUNET_ATS_NET_LAN; GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); /* Add peer 1 address 1 */ GAS_mlp_address_update (mlp, addresses, &addr[0]); mlpi = addr[0].mlp_information; GNUNET_assert (mlp != NULL); GNUNET_assert (mlp->addr_in_problem == 1); /* Update an peer 1 address 1 */ set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 20); GAS_mlp_address_update (mlp, addresses, &addr[0]); GNUNET_assert (mlp->addr_in_problem == 1); /* Update an peer 1 address 1 */ set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10); GAS_mlp_address_update (mlp, addresses, &addr[0]); GNUNET_assert (mlp->addr_in_problem == 1); /* Update an peer 1 address 1 */ set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10); GAS_mlp_address_update (mlp, addresses, &addr[0]); GNUNET_assert (mlp->addr_in_problem == 1); /* Update an peer 1 address 1 */ set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 30); GAS_mlp_address_update (mlp, addresses, &addr[0]); GNUNET_assert (mlp->addr_in_problem == 1); GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx)); GNUNET_assert (GNUNET_OK == ctx.lp_result); GNUNET_assert (GNUNET_OK == ctx.mlp_result); res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out); GNUNET_free (res[0]); /* Delete an address */ GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]); GAS_mlp_address_delete (mlp, addresses, &addr[0]); GNUNET_assert (mlp->addr_in_problem == 0); GAS_mlp_done (mlp); GNUNET_free (addr[0].plugin); GNUNET_CONTAINER_multihashmap_destroy (addresses); GNUNET_STATISTICS_destroy(stats, GNUNET_NO); ret = 0; return; }
static void update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n", GNUNET_i2s (&address->peer)); GNUNET_assert (NULL != address); GNUNET_assert (NULL != address->mlp_information); GNUNET_assert (NULL != address->ats); struct MLP_information *mlpi = address->mlp_information; struct GNUNET_ATS_Information *ats = address->ats; GNUNET_assert (mlpi != NULL); int c; for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) { int index = mlp_lookup_ats(address, mlp->q[c]); if (index == GNUNET_SYSERR) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), (double) ats[index].value); int i = mlpi->q_avg_i[c]; double * qp = mlpi->q[c]; qp[i] = (double) ats[index].value; int t; for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), t, qp[t]); } if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH)) mlpi->q_avg_i[c] ++; else mlpi->q_avg_i[c] = 0; int c2; int c3; double avg = 0.0; switch (mlp->q[c]) { case GNUNET_ATS_QUALITY_NET_DELAY: c3 = 0; for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++) { if (mlpi->q[c][c2] != -1) { double * t2 = mlpi->q[c] ; avg += t2[c2]; c3 ++; } } if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else mlpi->q_averaged[c] = 0.0; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), avg, avg / (double) c3, mlpi->q_averaged[c]); break; case GNUNET_ATS_QUALITY_NET_DISTANCE: c3 = 0; for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++) { if (mlpi->q[c][c2] != -1) { double * t2 = mlpi->q[c] ; avg += t2[c2]; c3 ++; } } if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else mlpi->q_averaged[c] = 0.0; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n", GNUNET_i2s (&address->peer), mlp_ats_to_string(mlp->q[c]), avg, avg / (double) c3, mlpi->q_averaged[c]); break; default: break; } if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0)) { /* Get current number of columns */ int found = GNUNET_NO; int cols = glp_get_num_cols(mlp->prob); int *ind = GNUNET_malloc (cols * sizeof (int) + 1); double *val = GNUNET_malloc (cols * sizeof (double) + 1); /* Get the matrix row of quality */ int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b); int c4; /* Get the index if matrix row of quality */ for (c4 = 1; c4 <= length; c4++ ) { if (mlpi->c_b == ind[c4]) { /* Update the value */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n", mlp_ats_to_string(mlp->q[c]), glp_get_col_name (mlp->prob, ind[c4]), glp_get_row_name (mlp->prob, mlp->r_q[c]), val[c4], mlpi->q_averaged[c]); val[c4] = mlpi->q_averaged[c]; found = GNUNET_YES; break; } } if (found == GNUNET_NO) { ind[length+1] = mlpi->c_b; val[length+1] = mlpi->q_averaged[c]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]: %i %f\n", length+1, length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]); glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val); } else { /* Get the index if matrix row of quality */ glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val); } GNUNET_free (ind); GNUNET_free (val); } } }
/** * Callback called from the zone iterator when we iterate over * the empty zone. Check that we got no records and then * start the actual tests by filling the zone. */ static void empty_zone_proc (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { char *hostkey_file; GNUNET_assert (nsh == cls); if (NULL != zone) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Expected empty zone but received zone private key\n")); GNUNET_break (0); if (endbadly_task != NULL) GNUNET_SCHEDULER_cancel (endbadly_task); endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); return; } if ((NULL != label) || (NULL != rd) || (0 != rd_count)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Expected no zone content but received data\n")); GNUNET_break (0); if (endbadly_task != NULL) GNUNET_SCHEDULER_cancel (endbadly_task); endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL); return; } zi = NULL; GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); privkey = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR, "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); privkey2 = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey2 != NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); GNUNET_asprintf(&s_name_1, "dummy1"); s_rd_1 = create_record(1); GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_1, 1, s_rd_1, &put_cont, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); GNUNET_asprintf(&s_name_2, "dummy2"); s_rd_2 = create_record(1); GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_2, 1, s_rd_2, &put_cont, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); /* name in different zone */ GNUNET_asprintf(&s_name_3, "dummy3"); s_rd_3 = create_record(1); GNUNET_NAMESTORE_records_store(nsh, privkey2, s_name_3, 1, s_rd_3, &put_cont, NULL); }
/** * Add constraints that are iterating over "forall addresses" * and collects all existing peers for "forall peers" constraints * * @param cls GAS_MLP_Handle * @param key Hashcode * @param value ATS_Address * * @return GNUNET_OK to continue */ static int create_constraint_it (void *cls, const GNUNET_HashCode * key, void *value) { struct GAS_MLP_Handle *mlp = cls; struct ATS_Address *address = value; struct MLP_information *mlpi; unsigned int row_index; char *name; GNUNET_assert (address->mlp_information != NULL); mlpi = (struct MLP_information *) address->mlp_information; /* c 1) bandwidth capping * b_t + (-M) * n_t <= 0 */ row_index = glp_add_rows (mlp->prob, 1); mlpi->r_c1 = row_index; /* set row name */ GNUNET_asprintf(&name, "c1_%s_%s", GNUNET_i2s(&address->peer), address->plugin); glp_set_row_name (mlp->prob, row_index, name); GNUNET_free (name); /* set row bounds: <= 0 */ glp_set_row_bnds (mlp->prob, row_index, GLP_UP, 0.0, 0.0); mlp->ia[mlp->ci] = row_index; mlp->ja[mlp->ci] = mlpi->c_b; mlp->ar[mlp->ci] = 1; mlp->ci++; mlp->ia[mlp->ci] = row_index; mlp->ja[mlp->ci] = mlpi->c_n; mlp->ar[mlp->ci] = -mlp->BIG_M; mlp->ci++; /* c 3) minimum bandwidth * b_t + (-n_t * b_min) >= 0 */ row_index = glp_add_rows (mlp->prob, 1); /* set row name */ GNUNET_asprintf(&name, "c3_%s_%s", GNUNET_i2s(&address->peer), address->plugin); glp_set_row_name (mlp->prob, row_index, name); GNUNET_free (name); mlpi->r_c3 = row_index; /* set row bounds: >= 0 */ glp_set_row_bnds (mlp->prob, row_index, GLP_LO, 0.0, 0.0); mlp->ia[mlp->ci] = row_index; mlp->ja[mlp->ci] = mlpi->c_b; mlp->ar[mlp->ci] = 1; mlp->ci++; mlp->ia[mlp->ci] = row_index; mlp->ja[mlp->ci] = mlpi->c_n; mlp->ar[mlp->ci] = - (double) mlp->b_min; mlp->ci++; /* c 4) minimum connections * (1)*n_1 + ... + (1)*n_m >= n_min */ mlp->ia[mlp->ci] = mlp->r_c4; mlp->ja[mlp->ci] = mlpi->c_n; mlp->ar[mlp->ci] = 1; mlp->ci++; /* c 6) maximize diversity * (1)*n_1 + ... + (1)*n_m - d == 0 */ mlp->ia[mlp->ci] = mlp->r_c6; mlp->ja[mlp->ci] = mlpi->c_n; mlp->ar[mlp->ci] = 1; mlp->ci++; /* c 10) obey network specific quotas * (1)*b_1 + ... + (1)*b_m <= quota_n */ int cur_row = 0; int c; for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) { if (mlp->quota_index[c] == address->atsp_network_type) { cur_row = mlp->r_quota[c]; break; } } if (cur_row != 0) { mlp->ia[mlp->ci] = cur_row; mlp->ja[mlp->ci] = mlpi->c_b; mlp->ar[mlp->ci] = 1; mlp->ci++; } else { GNUNET_break (0); } return GNUNET_OK; }
static void write_throughput_gnuplot_script (char * fn, struct LoggingPeer *lp, char **fs, int slaves) { struct GNUNET_DISK_FileHandle *f; char * gfn; char *data; int c_s; GNUNET_asprintf (&gfn, "gnuplot_throughput_%s",fn); fprintf (stderr, "Writing throughput plot for master %u and %u slaves to `%s'\n", lp->peer->no, slaves, gfn); f = GNUNET_DISK_file_open (gfn, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn); GNUNET_free (gfn); return; } /* Write header */ if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, THROUGHPUT_TEMPLATE, strlen(THROUGHPUT_TEMPLATE))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); /* Write master data */ GNUNET_asprintf (&data, "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \ "'%s' using 2:%u with lines title 'Master %u receive total', \\\n", fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no, fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); GNUNET_free (data); for (c_s = 0; c_s < slaves; c_s++) { GNUNET_asprintf (&data, "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \ "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n", fs[c_s], LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no, lp->peer->partners[c_s].dest->no, fs[c_s], LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no, lp->peer->partners[c_s].dest->no, (c_s < lp->peer->num_partners -1) ? ", \\" : "\n pause -1"); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); GNUNET_free (data); } if (GNUNET_SYSERR == GNUNET_DISK_file_close(f)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn); else GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn); GNUNET_free (gfn); }
static void mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses) { unsigned int n_addresses; int c; char *name; /* Problem matrix*/ n_addresses = GNUNET_CONTAINER_multihashmap_size(addresses); /* Required indices in the constrain matrix * * feasibility constraints: * * c 1) bandwidth capping * #rows: |n_addresses| * #indices: 2 * |n_addresses| * * c 2) one active address per peer * #rows: |peers| * #indices: |n_addresses| * * c 3) minium bandwidth assigned * #rows: |n_addresses| * #indices: 2 * |n_addresses| * * c 4) minimum number of active connections * #rows: 1 * #indices: |n_addresses| * * c 5) maximum ressource consumption * #rows: |ressources| * #indices: |n_addresses| * * c 10) obey network specific quota * #rows: |network types * #indices: |n_addresses| * * Sum for feasibility constraints: * #rows: 3 * |n_addresses| + |ressources| + |peers| + 1 * #indices: 7 * |n_addresses| * * optimality constraints: * * c 6) diversity * #rows: 1 * #indices: |n_addresses| + 1 * * c 7) quality * #rows: |quality properties| * #indices: |n_addresses| + |quality properties| * * c 8) utilization * #rows: 1 * #indices: |n_addresses| + 1 * * c 9) relativity * #rows: |peers| * #indices: |n_addresses| + |peers| * */ /* last +1 caused by glpk index starting with one: [1..pi]*/ int pi = ((7 * n_addresses) + (5 * n_addresses + mlp->m_q + mlp->c_p + 2) + 1); mlp->cm_size = pi; mlp->ci = 1; /* row index */ int *ia = GNUNET_malloc (pi * sizeof (int)); mlp->ia = ia; /* column index */ int *ja = GNUNET_malloc (pi * sizeof (int)); mlp->ja = ja; /* coefficient */ double *ar= GNUNET_malloc (pi * sizeof (double)); mlp->ar = ar; /* Adding constraint rows * This constraints are kind of "for all addresses" * Feasibility constraints: * * c 1) bandwidth capping * c 3) minimum bandwidth * c 4) minimum number of connections * c 6) maximize diversity * c 10) obey network specific quota */ /* Row for c4) minimum connection */ int min = mlp->n_min; /* Number of minimum connections is min(|Peers|, n_min) */ if (mlp->n_min > mlp->c_p) min = mlp->c_p; mlp->r_c4 = glp_add_rows (mlp->prob, 1); glp_set_row_name (mlp->prob, mlp->r_c4, "c4"); glp_set_row_bnds (mlp->prob, mlp->r_c4, GLP_LO, min, min); /* Add row for c6) */ mlp->r_c6 = glp_add_rows (mlp->prob, 1); /* Set type type to fix */ glp_set_row_bnds (mlp->prob, mlp->r_c6, GLP_FX, 0.0, 0.0); /* Setting -D */ ia[mlp->ci] = mlp->r_c6 ; ja[mlp->ci] = mlp->c_d; ar[mlp->ci] = -1; mlp->ci++; /* Add rows for c 10) */ for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) { mlp->r_quota[c] = glp_add_rows (mlp->prob, 1); char * text; GNUNET_asprintf(&text, "quota_ats_%i", mlp->quota_index[c]); glp_set_row_name (mlp->prob, mlp->r_quota[c], text); GNUNET_free (text); /* Set bounds to 0 <= x <= quota_out */ glp_set_row_bnds (mlp->prob, mlp->r_quota[c], GLP_UP, 0.0, mlp->quota_out[c]); } GNUNET_CONTAINER_multihashmap_iterate (addresses, create_constraint_it, mlp); /* Adding constraint rows * This constraints are kind of "for all peers" * Feasibility constraints: * * c 2) 1 address per peer * sum (n_p1_1 + ... + n_p1_n) = 1 * * c 8) utilization * sum (f_p * b_p1_1 + ... + f_p * b_p1_n) - u = 0 * * c 9) relativity * V p : sum (bt_1 + ... +bt_n) - f_p * r = 0 * */ /* Adding rows for c 8) */ mlp->r_c8 = glp_add_rows (mlp->prob, mlp->c_p); glp_set_row_name (mlp->prob, mlp->r_c8, "c8"); /* Set row bound == 0 */ glp_set_row_bnds (mlp->prob, mlp->r_c8, GLP_FX, 0.0, 0.0); /* -u */ ia[mlp->ci] = mlp->r_c8; ja[mlp->ci] = mlp->c_u; ar[mlp->ci] = -1; mlp->ci++; struct ATS_Peer * peer = mlp->peer_head; /* For all peers */ while (peer != NULL) { struct ATS_Address *addr = peer->head; struct MLP_information *mlpi = NULL; /* Adding rows for c 2) */ peer->r_c2 = glp_add_rows (mlp->prob, 1); GNUNET_asprintf(&name, "c2_%s", GNUNET_i2s(&peer->id)); glp_set_row_name (mlp->prob, peer->r_c2, name); GNUNET_free (name); /* Set row bound == 1 */ glp_set_row_bnds (mlp->prob, peer->r_c2, GLP_FX, 1.0, 1.0); /* Adding rows for c 9) */ #if ENABLE_C9 peer->r_c9 = glp_add_rows (mlp->prob, 1); GNUNET_asprintf(&name, "c9_%s", GNUNET_i2s(&peer->id)); glp_set_row_name (mlp->prob, peer->r_c9, name); GNUNET_free (name); /* Set row bound == 0 */ glp_set_row_bnds (mlp->prob, peer->r_c9, GLP_LO, 0.0, 0.0); /* Set -r */ ia[mlp->ci] = peer->r_c9; ja[mlp->ci] = mlp->c_r; ar[mlp->ci] = -peer->f; mlp->ci++; #endif /* For all addresses of this peer */ while (addr != NULL) { mlpi = (struct MLP_information *) addr->mlp_information; /* coefficient for c 2) */ ia[mlp->ci] = peer->r_c2; ja[mlp->ci] = mlpi->c_n; ar[mlp->ci] = 1; mlp->ci++; /* coefficient for c 8) */ ia[mlp->ci] = mlp->r_c8; ja[mlp->ci] = mlpi->c_b; ar[mlp->ci] = peer->f; mlp->ci++; #if ENABLE_C9 /* coefficient for c 9) */ ia[mlp->ci] = peer->r_c9; ja[mlp->ci] = mlpi->c_b; ar[mlp->ci] = 1; mlp->ci++; #endif addr = addr->next; } peer = peer->next; } /* c 7) For all quality metrics */ for (c = 0; c < mlp->m_q; c++) { struct ATS_Peer *tp; struct ATS_Address *ta; struct MLP_information * mlpi; double value = 1.0; /* Adding rows for c 7) */ mlp->r_q[c] = glp_add_rows (mlp->prob, 1); GNUNET_asprintf(&name, "c7_q%i_%s", c, mlp_ats_to_string(mlp->q[c])); glp_set_row_name (mlp->prob, mlp->r_q[c], name); GNUNET_free (name); /* Set row bound == 0 */ glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_FX, 0.0, 0.0); ia[mlp->ci] = mlp->r_q[c]; ja[mlp->ci] = mlp->c_q[c]; ar[mlp->ci] = -1; mlp->ci++; for (tp = mlp->peer_head; tp != NULL; tp = tp->next) for (ta = tp->head; ta != NULL; ta = ta->next) { mlpi = ta->mlp_information; value = mlpi->q_averaged[c]; mlpi->r_q[c] = mlp->r_q[c]; ia[mlp->ci] = mlp->r_q[c]; ja[mlp->ci] = mlpi->c_b; ar[mlp->ci] = tp->f_q[c] * value; mlp->ci++; } } }
/** * Iterate over the records given an optional peer id * and/or key. * * @param cls closure (internal context for the plugin) * @param sub_system name of sub system * @param peer Peer identity (can be NULL) * @param key entry key string (can be NULL) * @param iter function to call asynchronously with the results, terminated * by a NULL result * @param iter_cls closure for @a iter * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and iter is not * called */ static int peerstore_sqlite_iterate_records (void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor iter, void *iter_cls) { struct Plugin *plugin = cls; sqlite3_stmt *stmt; int err = 0; int sret; struct GNUNET_PEERSTORE_Record *ret; LOG (GNUNET_ERROR_TYPE_DEBUG, "Executing iterate request on sqlite db.\n"); if (NULL == peer && NULL == key) { stmt = plugin->select_peerstoredata; err = (SQLITE_OK != sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, SQLITE_STATIC)); } else if (NULL == key) { stmt = plugin->select_peerstoredata_by_pid; err = (SQLITE_OK != sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity), SQLITE_STATIC)); } else if (NULL == peer) { stmt = plugin->select_peerstoredata_by_key; err = (SQLITE_OK != sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_text (stmt, 2, key, strlen (key) + 1, SQLITE_STATIC)); } else { stmt = plugin->select_peerstoredata_by_all; err = (SQLITE_OK != sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1, SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity), SQLITE_STATIC)) || (SQLITE_OK != sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, SQLITE_STATIC)); } if (err) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); if (SQLITE_OK != sqlite3_reset (stmt)) LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); return GNUNET_SYSERR; } while (SQLITE_ROW == (sret = sqlite3_step (stmt))) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning a matched record.\n"); ret = GNUNET_new (struct GNUNET_PEERSTORE_Record); ret->sub_system = (char *) sqlite3_column_text (stmt, 0); ret->peer = (struct GNUNET_PeerIdentity *) sqlite3_column_blob (stmt, 1); ret->key = (char *) sqlite3_column_text (stmt, 2); ret->value = (void *) sqlite3_column_blob (stmt, 3); ret->value_size = sqlite3_column_bytes (stmt, 3); ret->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); ret->expiry->abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4); if (NULL != iter) iter (iter_cls, ret, NULL); GNUNET_free (ret->expiry); GNUNET_free (ret); } if (SQLITE_DONE != sret) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); err = 1; } if (SQLITE_OK != sqlite3_reset (stmt)) { LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); err = 1; } if (NULL != iter) { iter (iter_cls, NULL, err ? "sqlite error" : NULL); } return GNUNET_OK; }
/** * Create the MLP problem * * @param mlp the MLP handle * @param addresses the hashmap containing all adresses * @return GNUNET_OK or GNUNET_SYSERR */ static int mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses) { int res = GNUNET_OK; int col; int c; char *name; GNUNET_assert (mlp->prob == NULL); /* create the glpk problem */ mlp->prob = glp_create_prob (); /* Set a problem name */ glp_set_prob_name (mlp->prob, "gnunet ats bandwidth distribution"); /* Set optimization direction to maximize */ glp_set_obj_dir (mlp->prob, GLP_MAX); /* Adding invariant columns */ /* Diversity d column */ col = glp_add_cols (mlp->prob, 1); mlp->c_d = col; /* Column name */ glp_set_col_name (mlp->prob, col, "d"); /* Column objective function coefficient */ glp_set_obj_coef (mlp->prob, col, mlp->co_D); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); /* Utilization u column */ col = glp_add_cols (mlp->prob, 1); mlp->c_u = col; /* Column name */ glp_set_col_name (mlp->prob, col, "u"); /* Column objective function coefficient */ glp_set_obj_coef (mlp->prob, col, mlp->co_U); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); #if ENABLE_C9 /* Relativity r column */ col = glp_add_cols (mlp->prob, 1); mlp->c_r = col; /* Column name */ glp_set_col_name (mlp->prob, col, "r"); /* Column objective function coefficient */ glp_set_obj_coef (mlp->prob, col, mlp->co_R); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); #endif /* Quality metric columns */ col = glp_add_cols(mlp->prob, mlp->m_q); for (c = 0; c < mlp->m_q; c++) { mlp->c_q[c] = col + c; GNUNET_asprintf (&name, "q_%u", mlp->q[c]); glp_set_col_name (mlp->prob, col + c, name); /* Column lower bound = 0.0 */ glp_set_col_bnds (mlp->prob, col + c, GLP_LO, 0.0, 0.0); GNUNET_free (name); /* Coefficient == Qm */ glp_set_obj_coef (mlp->prob, col + c, mlp->co_Q[c]); } /* Add columns for addresses */ GNUNET_CONTAINER_multihashmap_iterate (addresses, create_columns_it, mlp); /* Add constraints */ mlp_add_constraints_all_addresses (mlp, addresses); /* Load the matrix */ glp_load_matrix(mlp->prob, (mlp->ci-1), mlp->ia, mlp->ja, mlp->ar); return res; }
/** * Convert the 'value' of a record to a string. * * @param type type of the record * @param data value in binary encoding * @param data_size number of bytes in data * @return NULL on error, otherwise human-readable representation of the value */ char * GNUNET_NAMESTORE_value_to_string (uint32_t type, const void *data, size_t data_size) { uint16_t mx_pref; const struct soa_data *soa; const struct vpn_data *vpn; const struct srv_data *srv; const struct tlsa_data *tlsa; struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc; struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; const char *cdata; char* vpn_str; char* srv_str; char* tlsa_str; char* result; const char* soa_rname; const char* soa_mname; char tmp[INET6_ADDRSTRLEN]; switch (type) { case 0: return NULL; case GNUNET_DNSPARSER_TYPE_A: if (data_size != sizeof (struct in_addr)) return NULL; if (NULL == inet_ntop (AF_INET, data, tmp, sizeof (tmp))) return NULL; return GNUNET_strdup (tmp); case GNUNET_DNSPARSER_TYPE_NS: return GNUNET_strndup (data, data_size); case GNUNET_DNSPARSER_TYPE_CNAME: return GNUNET_strndup (data, data_size); case GNUNET_DNSPARSER_TYPE_SOA: if (data_size <= sizeof (struct soa_data)) return NULL; soa = data; soa_rname = (const char*) &soa[1]; soa_mname = memchr (soa_rname, 0, data_size - sizeof (struct soa_data) - 1); if (NULL == soa_mname) return NULL; soa_mname++; if (NULL == memchr (soa_mname, 0, data_size - (sizeof (struct soa_data) + strlen (soa_rname) + 1))) return NULL; GNUNET_asprintf (&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", soa_rname, soa_mname, ntohl (soa->serial), ntohl (soa->refresh), ntohl (soa->retry), ntohl (soa->expire), ntohl (soa->minimum)); return result; case GNUNET_DNSPARSER_TYPE_PTR: return GNUNET_strndup (data, data_size); case GNUNET_DNSPARSER_TYPE_MX: mx_pref = ntohs(*((uint16_t*)data)); if (GNUNET_asprintf(&result, "%hu,%s", mx_pref, data+sizeof(uint16_t)) != 0) return result; else { GNUNET_free (result); return NULL; } case GNUNET_DNSPARSER_TYPE_TXT: return GNUNET_strndup (data, data_size); case GNUNET_DNSPARSER_TYPE_AAAA: if (data_size != sizeof (struct in6_addr)) return NULL; if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof (tmp))) return NULL; return GNUNET_strdup (tmp); case GNUNET_NAMESTORE_TYPE_PKEY: if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode)) return NULL; GNUNET_CRYPTO_short_hash_to_enc (data, &enc); return GNUNET_strdup ((const char*) enc.short_encoding); case GNUNET_NAMESTORE_TYPE_PSEU: return GNUNET_strndup (data, data_size); case GNUNET_NAMESTORE_TYPE_LEHO: return GNUNET_strndup (data, data_size); case GNUNET_NAMESTORE_TYPE_VPN: cdata = data; if ( (data_size <= sizeof (struct vpn_data)) || ('\0' != cdata[data_size - 1]) ) return NULL; /* malformed */ vpn = data; GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer); if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s", (unsigned int) ntohs (vpn->proto), (const char*) &s_peer, (const char*) &vpn[1])) { GNUNET_free (vpn_str); return NULL; } return vpn_str; case GNUNET_DNSPARSER_TYPE_SRV: cdata = data; if ( (data_size <= sizeof (struct srv_data)) || ('\0' != cdata[data_size - 1]) ) return NULL; /* malformed */ srv = data; if (0 == GNUNET_asprintf (&srv_str, "%d %d %d %s", ntohs (srv->prio), ntohs (srv->weight), ntohs (srv->port), (const char *)&srv[1])) { GNUNET_free (srv_str); return NULL; } return srv_str; case GNUNET_DNSPARSER_TYPE_TLSA: cdata = data; if ( (data_size <= sizeof (struct tlsa_data)) || ('\0' != cdata[data_size - 1]) ) return NULL; /* malformed */ tlsa = data; if (0 == GNUNET_asprintf (&tlsa_str, "%c %c %c %s", tlsa->usage, tlsa->selector, tlsa->matching_type, (const char *) &tlsa[1])) { GNUNET_free (tlsa_str); return NULL; } return tlsa_str; default: GNUNET_break (0); } GNUNET_break (0); // not implemented return NULL; }
/** * Publish a UBlock. * * @param h handle to the file sharing subsystem * @param dsh datastore handle to use for storage operation * @param label identifier to use * @param ulabel update label to use, may be an empty string for none * @param ns namespace to publish in * @param meta metadata to use * @param uri URI to refer to in the UBlock * @param bo per-block options * @param options publication options * @param cont continuation * @param cont_cls closure for @a cont * @return NULL on error (@a cont will still be called) */ struct GNUNET_FS_PublishUblockContext * GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, struct GNUNET_DATASTORE_Handle *dsh, const char *label, const char *ulabel, const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_BlockOptions *bo, enum GNUNET_FS_PublishOptions options, GNUNET_FS_UBlockContinuation cont, void *cont_cls) { struct GNUNET_FS_PublishUblockContext *uc; struct GNUNET_HashCode query; struct GNUNET_CRYPTO_SymmetricInitializationVector iv; struct GNUNET_CRYPTO_SymmetricSessionKey skey; struct GNUNET_CRYPTO_EcdsaPrivateKey *nsd; struct GNUNET_CRYPTO_EcdsaPublicKey pub; char *uris; size_t size; char *kbe; char *sptr; ssize_t mdsize; size_t slen; size_t ulen; struct UBlock *ub_plain; struct UBlock *ub_enc; /* compute ublock to publish */ if (NULL == meta) mdsize = 0; else mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); GNUNET_assert (mdsize >= 0); uris = GNUNET_FS_uri_to_string (uri); slen = strlen (uris) + 1; if (NULL == ulabel) ulen = 1; else ulen = strlen (ulabel) + 1; size = mdsize + sizeof (struct UBlock) + slen + ulen; if (size > MAX_UBLOCK_SIZE) { size = MAX_UBLOCK_SIZE; mdsize = size - sizeof (struct UBlock) - (slen + ulen); } ub_plain = GNUNET_malloc (size); kbe = (char *) &ub_plain[1]; if (NULL != ulabel) memcpy (kbe, ulabel, ulen); kbe += ulen; memcpy (kbe, uris, slen); kbe += slen; GNUNET_free (uris); sptr = kbe; if (NULL != meta) mdsize = GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize, GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); if (-1 == mdsize) { GNUNET_break (0); GNUNET_free (ub_plain); cont (cont_cls, _("Internal error.")); return NULL; } size = sizeof (struct UBlock) + slen + mdsize + ulen; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under identifier `%s'\n", label); /* get public key of the namespace */ GNUNET_CRYPTO_ecdsa_key_get_public (ns, &pub); derive_ublock_encryption_key (&skey, &iv, label, &pub); /* encrypt ublock */ ub_enc = GNUNET_malloc (size); GNUNET_CRYPTO_symmetric_encrypt (&ub_plain[1], ulen + slen + mdsize, &skey, &iv, &ub_enc[1]); GNUNET_free (ub_plain); ub_enc->purpose.size = htonl (ulen + slen + mdsize + sizeof (struct UBlock) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK); /* derive signing-key from 'label' and public key of the namespace */ nsd = GNUNET_CRYPTO_ecdsa_private_key_derive (ns, label, "fs-ublock"); GNUNET_CRYPTO_ecdsa_key_get_public (nsd, &ub_enc->verification_key); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (nsd, &ub_enc->purpose, &ub_enc->signature)); GNUNET_CRYPTO_hash (&ub_enc->verification_key, sizeof (ub_enc->verification_key), &query); GNUNET_free (nsd); uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext); uc->cont = cont; uc->cont_cls = cont_cls; uc->qre = GNUNET_DATASTORE_put (dsh, 0, &query, ulen + slen + mdsize + sizeof (struct UBlock), ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK, bo->content_priority, bo->anonymity_level, bo->replication_level, bo->expiration_time, -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, &ublock_put_cont, uc); return uc; }
/** * Iterator over hash map peer entries and frees all data in it. * Used prior to destroying a hashmap. Makes you miss anonymous functions in C. * * @param cls closure * @param key current key code (will no longer contain valid data!!) * @param value value in the hash map (treated as void *) * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not. */ static int iterate_free (void *cls, const struct GNUNET_HashCode * key, void *value) { GNUNET_free (value); return GNUNET_YES; }
/** * Abort UBlock publishing operation. * * @param uc operation to abort. */ void GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc) { GNUNET_DATASTORE_cancel (uc->qre); GNUNET_free (uc); }
/** * Handles a message sent from the DV service to us. * Parse it out and give it to the plugin. * * @param cls the handle to the DV API * @param msg the message that was received */ static void handle_message_receipt (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_DV_ServiceHandle *sh = cls; const struct GNUNET_DV_ConnectMessage *cm; const struct GNUNET_DV_DistanceUpdateMessage *dum; const struct GNUNET_DV_DisconnectMessage *dm; const struct GNUNET_DV_ReceivedMessage *rm; const struct GNUNET_MessageHeader *payload; const struct GNUNET_DV_AckMessage *ack; struct GNUNET_DV_TransmitHandle *th; struct GNUNET_DV_TransmitHandle *tn; struct ConnectedPeer *peer; if (NULL == msg) { /* Connection closed */ reconnect (sh); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u with %u bytes from DV service\n", (unsigned int) ntohs (msg->type), (unsigned int) ntohs (msg->size)); switch (ntohs (msg->type)) { case GNUNET_MESSAGE_TYPE_DV_CONNECT: if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ConnectMessage)) { GNUNET_break (0); reconnect (sh); return; } cm = (const struct GNUNET_DV_ConnectMessage *) msg; peer = GNUNET_CONTAINER_multipeermap_get (sh->peers, &cm->peer); if (NULL != peer) { GNUNET_break (0); reconnect (sh); return; } peer = GNUNET_new (struct ConnectedPeer); peer->pid = cm->peer; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (sh->peers, &peer->pid, peer, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); sh->connect_cb (sh->cls, &cm->peer, ntohl (cm->distance), (enum GNUNET_ATS_Network_Type) ntohl (cm->network)); break; case GNUNET_MESSAGE_TYPE_DV_DISTANCE_CHANGED: if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DistanceUpdateMessage)) { GNUNET_break (0); reconnect (sh); return; } dum = (const struct GNUNET_DV_DistanceUpdateMessage *) msg; sh->distance_cb (sh->cls, &dum->peer, ntohl (dum->distance), (enum GNUNET_ATS_Network_Type) ntohl (dum->network)); break; case GNUNET_MESSAGE_TYPE_DV_DISCONNECT: if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage)) { GNUNET_break (0); reconnect (sh); return; } dm = (const struct GNUNET_DV_DisconnectMessage *) msg; peer = GNUNET_CONTAINER_multipeermap_get (sh->peers, &dm->peer); if (NULL == peer) { GNUNET_break (0); reconnect (sh); return; } tn = sh->th_head; while (NULL != (th = tn)) { tn = th->next; if (peer == th->target) { GNUNET_CONTAINER_DLL_remove (sh->th_head, sh->th_tail, th); th->cb (th->cb_cls, GNUNET_SYSERR); GNUNET_free (th); } } cleanup_send_cb (sh, &dm->peer, peer); break; case GNUNET_MESSAGE_TYPE_DV_RECV: if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage) + sizeof (struct GNUNET_MessageHeader)) { GNUNET_break (0); reconnect (sh); return; } rm = (const struct GNUNET_DV_ReceivedMessage *) msg; payload = (const struct GNUNET_MessageHeader *) &rm[1]; if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ReceivedMessage) + ntohs (payload->size)) { GNUNET_break (0); reconnect (sh); return; } if (NULL == GNUNET_CONTAINER_multipeermap_get (sh->peers, &rm->sender)) { GNUNET_break (0); reconnect (sh); return; } sh->message_cb (sh->cls, &rm->sender, ntohl (rm->distance), payload); break; case GNUNET_MESSAGE_TYPE_DV_SEND_ACK: case GNUNET_MESSAGE_TYPE_DV_SEND_NACK: if (ntohs (msg->size) != sizeof (struct GNUNET_DV_AckMessage)) { GNUNET_break (0); reconnect (sh); return; } ack = (const struct GNUNET_DV_AckMessage *) msg; peer = GNUNET_CONTAINER_multipeermap_get (sh->peers, &ack->target); if (NULL == peer) break; /* this happens, just ignore */ for (th = peer->head; NULL != th; th = th->next) { if (th->uid != ntohl (ack->uid)) continue; LOG (GNUNET_ERROR_TYPE_DEBUG, "Matched ACK for message to peer %s\n", GNUNET_i2s (&ack->target)); GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, th); th->cb (th->cb_cls, (ntohs (ack->header.type) == GNUNET_MESSAGE_TYPE_DV_SEND_ACK) ? GNUNET_OK : GNUNET_SYSERR); GNUNET_free (th); break; } break; default: reconnect (sh); break; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message, continuing receive loop for %p\n", sh->client); GNUNET_CLIENT_receive (sh->client, &handle_message_receipt, sh, GNUNET_TIME_UNIT_FOREVER_REL); }
/** * 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); }
static void notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, const struct GNUNET_ATS_Information *ats, uint32_t ats_count) { struct PeerContext *p = cls; struct PeerContext *t = NULL; int c; if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity))) t = p1; if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity))) t = p2; GNUNET_assert (t != NULL); char *ps = GNUNET_strdup (GNUNET_i2s (&p->id)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%4s') received message of type %d and size %u size from peer %u (`%4s')!\n", p->no, ps, ntohs (message->type), ntohs (message->size), t->no, GNUNET_i2s (&t->id)); GNUNET_free (ps); if ((TEST_MESSAGE_TYPE == ntohs (message->type)) && (TEST_MESSAGE_SIZE == ntohs (message->size))) { ok = 0; } else { GNUNET_break (0); ok = 1; end (); return; } if (0 == messages_recv) { /* Received non-delayed message */ dur_normal = GNUNET_TIME_absolute_get_duration(start_normal); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received non-delayed message %u after %llu\n", messages_recv, (long long unsigned int) dur_normal.rel_value); send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); } if (1 == messages_recv) { /* Received manipulated message */ dur_delayed = GNUNET_TIME_absolute_get_duration(start_delayed); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received delayed message %u after %llu\n", messages_recv, (long long unsigned int) dur_delayed.rel_value); if (dur_delayed.rel_value < 1000) { GNUNET_break (0); ok += 1; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Delayed message was not delayed correctly: took only %llu\n", (long long unsigned int) dur_delayed.rel_value); } for (c = 0; c < ats_count; c++) { if (ntohl (ats[c].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) { if (ntohl (ats[c].value) == 10) ok += 0; else { GNUNET_break (0); ok += 1; } } } /* shutdown */ end (); } messages_recv ++; }
/** * Parse name inside of a DNS query or record. * * @param udp_payload entire UDP payload * @param udp_payload_length length of @a udp_payload * @param off pointer to the offset of the name to parse in the udp_payload (to be * incremented by the size of the name) * @param depth current depth of our recursion (to prevent stack overflow) * @return name as 0-terminated C string on success, NULL if the payload is malformed */ static char * parse_name (const char *udp_payload, size_t udp_payload_length, size_t *off, unsigned int depth) { const uint8_t *input = (const uint8_t *) udp_payload; char *ret; char *tmp; char *xstr; uint8_t len; size_t xoff; char *utf8; Idna_rc rc; ret = GNUNET_strdup (""); while (1) { if (*off >= udp_payload_length) { GNUNET_break_op (0); goto error; } len = input[*off]; if (0 == len) { (*off)++; break; } if (len < 64) { if (*off + 1 + len > udp_payload_length) { GNUNET_break_op (0); goto error; } GNUNET_asprintf (&tmp, "%.*s", (int) len, &udp_payload[*off + 1]); if (IDNA_SUCCESS != (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED))) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"), tmp, idna_strerror (rc)); GNUNET_free (tmp); GNUNET_asprintf (&tmp, "%s%.*s.", ret, (int) len, &udp_payload[*off + 1]); } else { GNUNET_free (tmp); GNUNET_asprintf (&tmp, "%s%s.", ret, utf8); #if WINDOWS idn_free (utf8); #else free (utf8); #endif } GNUNET_free (ret); ret = tmp; *off += 1 + len; } else if ((64 | 128) == (len & (64 | 128)) ) { if (depth > 32) { GNUNET_break_op (0); goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */ } /* pointer to string */ if (*off + 1 > udp_payload_length) { GNUNET_break_op (0); goto error; } xoff = ((len - (64 | 128)) << 8) + input[*off+1]; xstr = parse_name (udp_payload, udp_payload_length, &xoff, depth + 1); if (NULL == xstr) { GNUNET_break_op (0); goto error; } GNUNET_asprintf (&tmp, "%s%s.", ret, xstr); GNUNET_free (ret); GNUNET_free (xstr); ret = tmp; if (strlen (ret) > udp_payload_length) { GNUNET_break_op (0); goto error; /* we are looping (building an infinite string) */ } *off += 2; /* pointers always terminate names */ break; } else { /* neither pointer nor inline string, not supported... */ GNUNET_break_op (0); goto error; } } if (0 < strlen(ret)) ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */ return ret; error: GNUNET_break_op (0); GNUNET_free (ret); return NULL; }