/** * Callback method used with libcurl * Method is called when libcurl needs to write data during sending * * @param stream pointer where to write data * @param size size of an individual element * @param nmemb count of elements that can be written to the buffer * @param cls destination pointer, passed to the libcurl handle * @return bytes read from stream */ static size_t client_receive (void *stream, size_t size, size_t nmemb, void *cls) { struct Session *s = cls; struct GNUNET_TIME_Absolute now; size_t len = size * nmemb; struct Plugin *plugin = s->plugin; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Client: Received %Zu bytes from peer `%s'\n", len, GNUNET_i2s (&s->target)); now = GNUNET_TIME_absolute_get (); if (now.abs_value < s->next_receive.abs_value) { struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference (now, s->next_receive); GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Client: %p No inbound bandwidth available! Next read was delayed for %llu ms\n", s->client_get, delta.rel_value); if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; } s->recv_wakeup_task = GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s); return CURLPAUSE_ALL; } if (NULL == s->msg_tk) s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s); GNUNET_SERVER_mst_receive (s->msg_tk, s, stream, len, GNUNET_NO, GNUNET_NO); return len; }
static void pow_cb (void *cls, struct GNUNET_SENSOR_crypto_pow_block *block) { struct GNUNET_TIME_Absolute end_time; struct GNUNET_TIME_Relative duration; pow_task = NULL; end_time = GNUNET_TIME_absolute_get(); duration = GNUNET_TIME_absolute_get_difference (block->timestamp, end_time); printf("."); performed_iterations++; total_duration = GNUNET_TIME_relative_add (total_duration, duration); if (ITERATIONS == performed_iterations) { total_duration = GNUNET_TIME_relative_divide (total_duration, ITERATIONS); printf ("Matching bits %d: %s\n", current_matching_bits, GNUNET_STRINGS_relative_time_to_string(total_duration, GNUNET_NO)); total_duration = GNUNET_TIME_UNIT_ZERO; performed_iterations = 0; if (MATCHING_BITS_END == current_matching_bits) { ok = 0; GNUNET_SCHEDULER_cancel (shutdown_task); GNUNET_SCHEDULER_add_now (do_shutdown, NULL); return; } current_matching_bits ++; } GNUNET_SCHEDULER_add_now (&pow_start, NULL); }
/** * Iterate over the expired items stored in the datastore. * Delete all expired items; once we have processed all * expired items, re-schedule the "delete_expired" task. * * @param cls not used * @param key key for the content * @param size number of bytes in data * @param data content stored * @param type type of the content * @param priority priority of the content * @param anonymity anonymity-level for the content * @param expiration expiration time for the content * @param uid unique identifier for the datum; * maybe 0 if no unique identifier is available * * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue * (continue on call to "next", of course), * GNUNET_NO to delete the item and continue (if supported) */ static int expired_processor (void *cls, const struct GNUNET_HashCode * key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, uint64_t uid) { struct GNUNET_TIME_Absolute now; if (key == NULL) { expired_kill_task = GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY, GNUNET_SCHEDULER_PRIORITY_IDLE, &delete_expired, NULL); return GNUNET_SYSERR; } now = GNUNET_TIME_absolute_get (); if (expiration.abs_value_us > now.abs_value_us) { /* finished processing */ expired_kill_task = GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY, GNUNET_SCHEDULER_PRIORITY_IDLE, &delete_expired, NULL); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting content `%s' of type %u that expired %s ago\n", GNUNET_h2s (key), type, GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_difference (expiration, now), GNUNET_YES)); min_expiration = now; GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes expired"), size, GNUNET_YES); GNUNET_CONTAINER_bloomfilter_remove (filter, key); expired_kill_task = GNUNET_SCHEDULER_add_delayed_with_priority (MIN_EXPIRE_DELAY, GNUNET_SCHEDULER_PRIORITY_IDLE, &delete_expired, NULL); return GNUNET_NO; }
/** * Show the results of the test (banwidth acheived) and log them to GAUGER */ static void show_end_data (void) { static struct GNUNET_TIME_Absolute end_time; static struct GNUNET_TIME_Relative total_time; end_time = GNUNET_TIME_absolute_get(); total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time); FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name); FPRINTF (stderr, "Test time %s\n", GNUNET_STRINGS_relative_time_to_string (total_time, GNUNET_YES)); FPRINTF (stderr, "Test bandwidth: %f kb/s\n", 4 * TOTAL_PACKETS * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms FPRINTF (stderr, "Test throughput: %f packets/s\n\n", TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms GAUGER ("CADET", test_name, TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000), "packets/s"); }
static int expire_blocks (void *cls, const struct GNUNET_HashCode *key, void *value) { struct Plugin *plugin = cls; struct FlatFileEntry *entry = value; struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute expiration; now = GNUNET_TIME_absolute_get (); expiration = GNUNET_TIME_absolute_ntoh (entry->block->expiration_time); if (0 == GNUNET_TIME_absolute_get_difference (now, expiration).rel_value_us) { GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, key); } return GNUNET_YES; }
void GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p) { struct GNUNET_TIME_Relative left; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Master [%u]: Received PONG from [%u], next message\n", p->me->no, p->dest->no); p->messages_received++; p->bytes_received += TEST_MESSAGE_SIZE; p->me->total_messages_received++; p->me->total_bytes_received += TEST_MESSAGE_SIZE; p->total_app_rtt += GNUNET_TIME_absolute_get_difference(p->last_message_sent, GNUNET_TIME_absolute_get()).rel_value_us; /* Schedule next send event */ if (NULL == p->tg) return; left = GNUNET_TIME_absolute_get_remaining(p->tg->next_ping_transmission); if (UINT32_MAX == p->tg->base_rate) { p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p); } else if (0 == left.rel_value_us) { p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p); } else { /* Enforce minimum transmission rate 1 msg / sec */ if (GNUNET_TIME_UNIT_SECONDS.rel_value_us == (left = GNUNET_TIME_relative_min (left, GNUNET_TIME_UNIT_SECONDS)).rel_value_us) GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Enforcing minimum send rate between master [%u] and slave [%u]\n", p->me->no, p->dest->no); p->tg->send_task = GNUNET_SCHEDULER_add_delayed (left, &comm_schedule_send, p); } }
/** * Log all data now * * @param l logging handle to use */ void GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l) { struct LoggingPeer *bp; struct PeerLoggingTimestep *mlt; struct PeerLoggingTimestep *prev_log_mlt; struct PartnerLoggingTimestep *slt; struct PartnerLoggingTimestep *prev_log_slt; struct BenchmarkPartner *p; struct GNUNET_TIME_Relative delta; int c_s; int c_m; unsigned int app_rtt; double mult; if (GNUNET_YES != l->running) return; for (c_m = 0; c_m < l->num_masters; c_m++) { bp = &l->lp[c_m]; mlt = GNUNET_new (struct PeerLoggingTimestep); GNUNET_CONTAINER_DLL_insert_tail(l->lp[c_m].head, l->lp[c_m].tail, mlt); prev_log_mlt = mlt->prev; /* Collect data */ /* Current master state */ mlt->timestamp = GNUNET_TIME_absolute_get(); mlt->total_bytes_sent = bp->peer->total_bytes_sent; mlt->total_messages_sent = bp->peer->total_messages_sent; mlt->total_bytes_received = bp->peer->total_bytes_received; mlt->total_messages_received = bp->peer->total_messages_received; /* Throughput */ if (NULL == prev_log_mlt) { /* Get difference to start */ delta = GNUNET_TIME_absolute_get_difference (l->lp[c_m].start, mlt->timestamp); } else { /* Get difference to last timestep */ delta = GNUNET_TIME_absolute_get_difference (mlt->prev->timestamp, mlt->timestamp); } /* Multiplication factor for throughput calculation */ mult = (double) GNUNET_TIME_UNIT_SECONDS.rel_value_us / (delta.rel_value_us); /* Total throughput */ if (NULL != prev_log_mlt) { if (mlt->total_bytes_sent - mlt->prev->total_bytes_sent > 0) { mlt->total_throughput_send = mult * (mlt->total_bytes_sent - mlt->prev->total_bytes_sent); } else { mlt->total_throughput_send = 0; // mlt->total_throughput_send = prev_log_mlt->total_throughput_send; /* no msgs send */ } if (mlt->total_bytes_received - mlt->prev->total_bytes_received > 0) { mlt->total_throughput_recv = mult * (mlt->total_bytes_received - mlt->prev->total_bytes_received); } else { mlt->total_throughput_send = 0; //mlt->total_throughput_recv = prev_log_mlt->total_throughput_recv; /* no msgs received */ } } else { mlt->total_throughput_send = mult * mlt->total_bytes_sent; mlt->total_throughput_send = mult * mlt->total_bytes_received; } if (GNUNET_YES == l->verbose) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Master[%u] delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n", c_m, delta.rel_value_us, mlt->total_bytes_sent, mlt->total_bytes_received, mlt->total_throughput_send, mlt->total_throughput_recv); } mlt->slaves_log = GNUNET_malloc (bp->peer->num_partners * sizeof (struct PartnerLoggingTimestep)); for (c_s = 0; c_s < bp->peer->num_partners; c_s++) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Collect logging data master[%u] slave [%u]\n", c_m, c_s); p = &bp->peer->partners[c_s]; slt = &mlt->slaves_log[c_s]; slt->slave = p->dest; /* Bytes sent from master to this slave */ slt->total_bytes_sent = p->bytes_sent; /* Messages sent from master to this slave */ slt->total_messages_sent = p->messages_sent; /* Bytes master received from this slave */ slt->total_bytes_received = p->bytes_received; /* Messages master received from this slave */ slt->total_messages_received = p->messages_received; slt->total_app_rtt = p->total_app_rtt; /* ats performance information */ slt->ats_delay = p->props.delay; slt->ats_distance = p->props.distance; slt->ats_network_type = p->props.scope; slt->ats_utilization_in = p->props.utilization_out; slt->ats_utilization_out = p->props.utilization_out; slt->bandwidth_in = p->bandwidth_in; slt->bandwidth_out = p->bandwidth_out; slt->pref_bandwidth = p->pref_bandwidth; slt->pref_delay = p->pref_delay; /* Total application level rtt */ if (NULL == prev_log_mlt) { if (0 != slt->total_messages_sent) app_rtt = slt->total_app_rtt / slt->total_messages_sent; else app_rtt = 0; } else { prev_log_slt = &prev_log_mlt->slaves_log[c_s]; if ((slt->total_messages_sent - prev_log_slt->total_messages_sent) > 0) app_rtt = (slt->total_app_rtt - prev_log_slt->total_app_rtt) / (slt->total_messages_sent - prev_log_slt->total_messages_sent); else { app_rtt = prev_log_slt->app_rtt; /* No messages were */ } } slt->app_rtt = app_rtt; /* Partner throughput */ if (NULL != prev_log_mlt) { prev_log_slt = &prev_log_mlt->slaves_log[c_s]; if (slt->total_bytes_sent > prev_log_slt->total_bytes_sent) slt->throughput_sent = mult * (slt->total_bytes_sent - prev_log_slt->total_bytes_sent); else slt->throughput_sent = 0; if (slt->total_bytes_received > prev_log_slt->total_bytes_received) slt->throughput_recv = mult * (slt->total_bytes_received - prev_log_slt->total_bytes_received); else slt->throughput_recv = 0; } else { slt->throughput_sent = mult * slt->total_bytes_sent; slt->throughput_recv = mult * slt->total_bytes_received; } if (GNUNET_YES == l->verbose) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Master [%u] -> Slave [%u]: delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n", c_m, c_s, delta.rel_value_us, mlt->total_bytes_sent, mlt->total_bytes_received, slt->throughput_sent, slt->throughput_recv); } else GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Master [%u]: slave [%u]\n", bp->peer->no, p->dest->no); } } }
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]); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close(f_m)); GNUNET_free (filename_master); 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;%.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_delay, plt->ats_distance, plt->ats_network_type, plt->ats_utilization_out, plt->ats_utilization_in, plt->pref_bandwidth, plt->pref_delay); if (l->verbose) fprintf (stderr, "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %llu 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, (long long unsigned int) plt->ats_delay.rel_value_us, 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); continue; } 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_strerror_file (GNUNET_ERROR_TYPE_ERROR, "close", filename_master); GNUNET_free (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); } } GNUNET_free (filename_master); }
int main (int argc, char *argv[]) { struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_AbsoluteNBO nown; struct GNUNET_TIME_Absolute future; struct GNUNET_TIME_Absolute past; struct GNUNET_TIME_Absolute last; struct GNUNET_TIME_Absolute forever; struct GNUNET_TIME_Absolute zero; struct GNUNET_TIME_Relative rel; struct GNUNET_TIME_Relative relForever; struct GNUNET_TIME_Relative relUnit; struct GNUNET_TIME_RelativeNBO reln; unsigned int i; GNUNET_log_setup ("test-time", "WARNING", NULL); forever = GNUNET_TIME_UNIT_FOREVER_ABS; relForever = GNUNET_TIME_UNIT_FOREVER_REL; relUnit = GNUNET_TIME_UNIT_MILLISECONDS; zero.abs_value_us = 0; last = now = GNUNET_TIME_absolute_get (); while (now.abs_value_us == last.abs_value_us) now = GNUNET_TIME_absolute_get (); GNUNET_assert (now.abs_value_us > last.abs_value_us); /* test overflow checking in multiply */ rel = GNUNET_TIME_UNIT_MILLISECONDS; GNUNET_log_skip (1, GNUNET_NO); for (i = 0; i < 55; i++) rel = GNUNET_TIME_relative_multiply (rel, 2); GNUNET_log_skip (0, GNUNET_NO); GNUNET_assert (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us); /*check zero */ rel.rel_value_us = (UINT64_MAX) - 1024; GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us == GNUNET_TIME_relative_multiply (rel, 0).rel_value_us); /* test infinity-check for relative to absolute */ GNUNET_log_skip (1, GNUNET_NO); last = GNUNET_TIME_relative_to_absolute (rel); GNUNET_assert (last.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us); GNUNET_log_skip (0, GNUNET_YES); /* check relative to absolute */ rel.rel_value_us = 1000000; GNUNET_assert (GNUNET_TIME_absolute_get ().abs_value_us < GNUNET_TIME_relative_to_absolute (rel).abs_value_us); /*check forever */ rel.rel_value_us = UINT64_MAX; GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == GNUNET_TIME_relative_to_absolute (rel).abs_value_us); /* check overflow for r2a */ rel.rel_value_us = (UINT64_MAX) - 1024; GNUNET_log_skip (1, GNUNET_NO); last = GNUNET_TIME_relative_to_absolute (rel); GNUNET_log_skip (0, GNUNET_NO); GNUNET_assert (last.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us); /* check overflow for relative add */ GNUNET_log_skip (1, GNUNET_NO); rel = GNUNET_TIME_relative_add (rel, rel); GNUNET_log_skip (0, GNUNET_NO); GNUNET_assert (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us); GNUNET_log_skip (1, GNUNET_NO); rel = GNUNET_TIME_relative_add (relForever, relForever); GNUNET_log_skip (0, GNUNET_NO); GNUNET_assert (rel.rel_value_us == relForever.rel_value_us); GNUNET_log_skip (1, GNUNET_NO); rel = GNUNET_TIME_relative_add (relUnit, relUnit); GNUNET_assert (rel.rel_value_us == 2 * relUnit.rel_value_us); /* check relation check in get_duration */ future.abs_value_us = now.abs_value_us + 1000000; GNUNET_assert (GNUNET_TIME_absolute_get_difference (now, future).rel_value_us == 1000000); GNUNET_assert (GNUNET_TIME_absolute_get_difference (future, now).rel_value_us == 0); GNUNET_assert (GNUNET_TIME_absolute_get_difference (zero, forever).rel_value_us == forever.abs_value_us); past.abs_value_us = now.abs_value_us - 1000000; rel = GNUNET_TIME_absolute_get_duration (future); GNUNET_assert (rel.rel_value_us == 0); rel = GNUNET_TIME_absolute_get_duration (past); GNUNET_assert (rel.rel_value_us >= 1000000); /* check get remaining */ rel = GNUNET_TIME_absolute_get_remaining (now); GNUNET_assert (rel.rel_value_us == 0); rel = GNUNET_TIME_absolute_get_remaining (past); GNUNET_assert (rel.rel_value_us == 0); rel = GNUNET_TIME_absolute_get_remaining (future); GNUNET_assert (rel.rel_value_us > 0); GNUNET_assert (rel.rel_value_us <= 1000000); forever = GNUNET_TIME_UNIT_FOREVER_ABS; GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == GNUNET_TIME_absolute_get_remaining (forever).rel_value_us); /* check endianess */ reln = GNUNET_TIME_relative_hton (rel); GNUNET_assert (rel.rel_value_us == GNUNET_TIME_relative_ntoh (reln).rel_value_us); nown = GNUNET_TIME_absolute_hton (now); GNUNET_assert (now.abs_value_us == GNUNET_TIME_absolute_ntoh (nown).abs_value_us); /* check absolute addition */ future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_SECONDS); GNUNET_assert (future.abs_value_us == now.abs_value_us + 1000 * 1000LL); future = GNUNET_TIME_absolute_add (forever, GNUNET_TIME_UNIT_ZERO); GNUNET_assert (future.abs_value_us == forever.abs_value_us); rel.rel_value_us = (UINT64_MAX) - 1024; now.abs_value_us = rel.rel_value_us; future = GNUNET_TIME_absolute_add (now, rel); GNUNET_assert (future.abs_value_us == forever.abs_value_us); /* check zero */ future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_ZERO); GNUNET_assert (future.abs_value_us == now.abs_value_us); GNUNET_assert (forever.abs_value_us == GNUNET_TIME_absolute_subtract (forever, GNUNET_TIME_UNIT_MINUTES).abs_value_us); /*check absolute subtract */ now.abs_value_us = 50000; rel.rel_value_us = 100000; GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == (GNUNET_TIME_absolute_subtract (now, rel)).abs_value_us); rel.rel_value_us = 10000; GNUNET_assert (40000 == (GNUNET_TIME_absolute_subtract (now, rel)).abs_value_us); /*check relative divide */ GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == (GNUNET_TIME_relative_divide (rel, 0)).rel_value_us); rel = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == (GNUNET_TIME_relative_divide (rel, 2)).rel_value_us); rel = GNUNET_TIME_relative_divide (relUnit, 2); GNUNET_assert (rel.rel_value_us == relUnit.rel_value_us / 2); /* check Return absolute time of 0ms */ zero = GNUNET_TIME_UNIT_ZERO_ABS; /* check GNUNET_TIME_calculate_eta */ last.abs_value_us = GNUNET_TIME_absolute_get ().abs_value_us - 1024; forever = GNUNET_TIME_UNIT_FOREVER_ABS; forever.abs_value_us = forever.abs_value_us - 1024; GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == GNUNET_TIME_calculate_eta (forever, 50000, 100000).rel_value_us); /* check zero */ GNUNET_log_skip (1, GNUNET_NO); GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us == (GNUNET_TIME_calculate_eta (last, 60000, 50000)).rel_value_us); GNUNET_log_skip (0, GNUNET_YES); /*check forever */ GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == (GNUNET_TIME_calculate_eta (last, 0, 50000)).rel_value_us); /*check relative subtract */ now = GNUNET_TIME_absolute_get (); rel.rel_value_us = now.abs_value_us; relForever.rel_value_us = rel.rel_value_us + 1024; GNUNET_assert (1024 == GNUNET_TIME_relative_subtract (relForever, rel).rel_value_us); /*check zero */ GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us == GNUNET_TIME_relative_subtract (rel, relForever).rel_value_us); /*check forever */ rel.rel_value_us = UINT64_MAX; GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == GNUNET_TIME_relative_subtract (rel, relForever).rel_value_us); /*check GNUNET_TIME_relative_min */ now = GNUNET_TIME_absolute_get (); rel.rel_value_us = now.abs_value_us; relForever.rel_value_us = rel.rel_value_us - 1024; GNUNET_assert (relForever.rel_value_us == GNUNET_TIME_relative_min (rel, relForever).rel_value_us); /*check GNUNET_TIME_relative_max */ GNUNET_assert (rel.rel_value_us == GNUNET_TIME_relative_max (rel, relForever).rel_value_us); /*check GNUNET_TIME_absolute_min */ now = GNUNET_TIME_absolute_get (); last.abs_value_us = now.abs_value_us - 1024; GNUNET_assert (last.abs_value_us == GNUNET_TIME_absolute_min (now, last).abs_value_us); /*check GNUNET_TIME_absolute_max */ GNUNET_assert (now.abs_value_us == GNUNET_TIME_absolute_max (now, last).abs_value_us); return 0; }
/** * Solves the MLP problem * * @param mlp the MLP Handle * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Absolute end; struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get(); /* solve MLP problem */ res = glp_intopt(mlp->prob, &mlp->control_param_mlp); if (res == 0) { /* The MLP problem instance has been successfully solved. */ } else if (res == GLP_EITLIM) { /* simplex iteration limit has been exceeded. */ // TODO Increase iteration limit? } else if (res == GLP_ETMLIM) { /* Time limit has been exceeded. */ // TODO Increase time limit? } else { /* Problem was ill-defined, no way to handle that */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-mlp", "Solving MLP problem failed: %s\n", mlp_solve_to_string(res)); return GNUNET_SYSERR; } end = GNUNET_TIME_absolute_get (); duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->mlp_solved++; mlp->mlp_total_duration =+ duration.rel_value; s_ctx->mlp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO); GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", duration.rel_value, GNUNET_NO); GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)", mlp->mlp_total_duration / mlp->mlp_solved, GNUNET_NO); /* Analyze problem status */ res = glp_mip_status(mlp->prob); switch (res) { /* solution is optimal */ case GLP_OPT: /* solution is feasible */ case GLP_FEAS: break; /* Problem was ill-defined, no way to handle that */ default: GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-mlp", "Solving MLP problem failed, %s\n\n", mlp_status_to_string(res)); return GNUNET_SYSERR; break; } return GNUNET_OK; }
/** * Solves the LP problem * * @param mlp the MLP Handle * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ static int mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Absolute end; struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get(); /* LP presolver? * Presolver is required if the problem was modified and an existing * valid basis is now invalid */ if (mlp->presolver_required == GNUNET_YES) mlp->control_param_lp.presolve = GLP_ON; else mlp->control_param_lp.presolve = GLP_OFF; /* Solve LP problem to have initial valid solution */ lp_solv: res = glp_simplex(mlp->prob, &mlp->control_param_lp); if (res == 0) { /* The LP problem instance has been successfully solved. */ } else if (res == GLP_EITLIM) { /* simplex iteration limit has been exceeded. */ // TODO Increase iteration limit? } else if (res == GLP_ETMLIM) { /* Time limit has been exceeded. */ // TODO Increase time limit? } else { /* Problem was ill-defined, retry with presolver */ if (mlp->presolver_required == GNUNET_NO) { mlp->presolver_required = GNUNET_YES; goto lp_solv; } else { /* Problem was ill-defined, no way to handle that */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-mlp", "Solving LP problem failed: %i %s\n", res, mlp_solve_to_string(res)); return GNUNET_SYSERR; } } end = GNUNET_TIME_absolute_get (); duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->lp_solved++; mlp->lp_total_duration =+ duration.rel_value; s_ctx->lp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO); GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", duration.rel_value, GNUNET_NO); GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)", mlp->lp_total_duration / mlp->lp_solved, GNUNET_NO); /* Analyze problem status */ res = glp_get_status (mlp->prob); switch (res) { /* solution is optimal */ case GLP_OPT: /* solution is feasible */ case GLP_FEAS: break; /* Problem was ill-defined, no way to handle that */ default: GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-mlp", "Solving LP problem failed, no solution: %s\n", mlp_status_to_string(res)); return GNUNET_SYSERR; break; } /* solved sucessfully, no presolver required next time */ mlp->presolver_required = GNUNET_NO; return GNUNET_OK; }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { size_t len; int c; int rd_count = 3; size_t data_len; struct GNUNET_NAMESTORE_RecordData src[rd_count]; memset(src, '\0', rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); data_len = 0; for (c = 0; c < rd_count; c++) { src[c].record_type = c+1; src[c].data_size = data_len; src[c].data = GNUNET_malloc (data_len); /* Setting data to data_len * record_type */ memset ((char *) src[c].data, 'a', data_len); data_len += 10; } res = 0; len = GNUNET_NAMESTORE_records_get_size(rd_count, src); char rd_ser[len]; GNUNET_assert (len == GNUNET_NAMESTORE_records_serialize(rd_count, src, len, rd_ser)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized data len: %u\n",len); GNUNET_assert (rd_ser != NULL); struct GNUNET_NAMESTORE_RecordData dst[rd_count]; GNUNET_assert (GNUNET_OK == GNUNET_NAMESTORE_records_deserialize (len, rd_ser, rd_count, dst)); GNUNET_assert (dst != NULL); for (c = 0; c < rd_count; c++) { if (src[c].data_size != dst[c].data_size) { GNUNET_break (0); res = 1; } if (0 != GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value) { GNUNET_break (0); res = 1; } if (src[c].flags != dst[c].flags) { GNUNET_break (0); res = 1; } if (src[c].record_type != dst[c].record_type) { GNUNET_break (0); res = 1; } size_t data_size = src[c].data_size; char data[data_size]; memset (data, 'a', data_size); if (0 != memcmp (data, dst[c].data, data_size)) { GNUNET_break (0); res = 1; } if (0 != memcmp (data, src[c].data, data_size)) { GNUNET_break (0); res = 1; } if (0 != memcmp (src[c].data, dst[c].data, src[c].data_size)) { GNUNET_break (0); res = 1; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c); } for (c = 0; c < rd_count; c++) { GNUNET_free ((void *)src[c].data); } }
/** * Find a "good" address to use for a peer. If we already have an existing * address, we stick to it. Otherwise, we pick by lowest distance and then * by lowest latency. * * @param cls the 'struct ATS_Address**' where we store the result * @param key unused * @param value another 'struct ATS_Address*' to consider using * @return GNUNET_OK (continue to iterate) */ static int find_address_it (void *cls, const GNUNET_HashCode * key, void *value) { struct ATS_Address **ap = cls; struct ATS_Address *aa = (struct ATS_Address *) value; struct ATS_Address *ab = *ap; struct GNUNET_TIME_Absolute now; now = GNUNET_TIME_absolute_get(); if (aa->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, aa->blocked_until).abs_value) { /* This address is blocked for suggestion */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Address %p blocked for suggestion for %llu ms \n", aa, GNUNET_TIME_absolute_get_difference(now, aa->blocked_until).rel_value); return GNUNET_OK; } aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, ATS_BLOCKING_DELTA); aa->blocked_until = GNUNET_TIME_absolute_add (now, aa->block_interval); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Address %p ready for suggestion, block interval now %llu \n", aa, aa->block_interval); /* FIXME this is a hack */ if (NULL != ab) { if ((0 == strcmp (ab->plugin, "tcp")) && (0 == strcmp (aa->plugin, "tcp"))) { if ((0 != ab->addr_len) && (0 == aa->addr_len)) { /* saved address was an outbound address, but we have an inbound address */ *ap = aa; return GNUNET_OK; } if (0 == ab->addr_len) { /* saved address was an inbound address, so do not overwrite */ return GNUNET_OK; } } } /* FIXME end of hack */ if (NULL == ab) { *ap = aa; return GNUNET_OK; } if ((ntohl (ab->assigned_bw_in.value__) == 0) && (ntohl (aa->assigned_bw_in.value__) > 0)) { /* stick to existing connection */ *ap = aa; return GNUNET_OK; } if (ab->atsp_distance > aa->atsp_distance) { /* user shorter distance */ *ap = aa; return GNUNET_OK; } if (ab->atsp_latency.rel_value > aa->atsp_latency.rel_value) { /* user lower latency */ *ap = aa; return GNUNET_OK; } /* don't care */ return GNUNET_OK; }
/** * Information callback for the solver * * @param op the solver operation * @param stat status of the solver operation * @param add additional solver information */ static void solver_info_cb (void *cls, enum GAS_Solver_Operation op, enum GAS_Solver_Status stat, enum GAS_Solver_Additional_Information add) { char *add_info; switch (add) { case GAS_INFO_NONE: add_info = "GAS_INFO_NONE"; break; case GAS_INFO_FULL: add_info = "GAS_INFO_MLP_FULL"; break; case GAS_INFO_UPDATED: add_info = "GAS_INFO_MLP_UPDATED"; break; case GAS_INFO_PROP_ALL: add_info = "GAS_INFO_PROP_ALL"; break; case GAS_INFO_PROP_SINGLE: add_info = "GAS_INFO_PROP_SINGLE"; break; default: add_info = "INVALID"; break; } struct Result *tmp; switch (op) { case GAS_OP_SOLVE_START: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info); if (GNUNET_NO == ph.expecting_solution) { /* We do not expect a solution at the moment */ GNUNET_break (0); return; } if ((GAS_STAT_SUCCESS == stat) && (NULL == ph.current_result)) { tmp = GNUNET_new (struct Result); /* Create new result */ if ((add == GAS_INFO_UPDATED) || (GNUNET_YES == ph.performed_update)) { ph.current_result = tmp; //fprintf (stderr,"UPDATE %u %u\n",ph.current_iteration-1, ph.current_p); ph.iterations_results[ph.current_iteration-1].update_results_array[ph.current_p] = tmp; } else { ph.current_result = tmp; //fprintf (stderr,"FULL %u %u\n",ph.current_iteration-1, ph.current_p); ph.iterations_results[ph.current_iteration-1].results_array[ph.current_p] = tmp; } ph.current_result->addresses = ph.current_a; ph.current_result->peers = ph.current_p; ph.current_result->s_total = GNUNET_TIME_absolute_get(); ph.current_result->d_total_full = GNUNET_TIME_UNIT_FOREVER_REL; ph.current_result->d_setup_full = GNUNET_TIME_UNIT_FOREVER_REL; ph.current_result->d_lp_full = GNUNET_TIME_UNIT_FOREVER_REL; ph.current_result->d_mlp_full = GNUNET_TIME_UNIT_FOREVER_REL; ph.current_result->info = add; if ((add == GAS_INFO_UPDATED) || (GNUNET_YES == ph.performed_update)) { ph.current_result->update = GNUNET_YES; } else { ph.current_result->update = GNUNET_NO; } } return; case GAS_OP_SOLVE_STOP: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s', `%s'\n", "GAS_OP_SOLVE_STOP", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { /* We do not expect a solution at the moment */ GNUNET_break (0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; if (NULL != ph.current_result) { /* Finalize result */ ph.current_result->e_total = GNUNET_TIME_absolute_get (); ph.current_result->d_total_full = GNUNET_TIME_absolute_get_difference ( ph.current_result->s_total, ph.current_result->e_total); } ph.current_result = NULL; return; case GAS_OP_SOLVE_SETUP_START: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { GNUNET_break(0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; ph.current_result->s_setup = GNUNET_TIME_absolute_get (); return; case GAS_OP_SOLVE_SETUP_STOP: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { GNUNET_break(0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; ph.current_result->e_setup = GNUNET_TIME_absolute_get (); ph.current_result->d_setup_full = GNUNET_TIME_absolute_get_difference ( ph.current_result->s_setup, ph.current_result->e_setup); return; case GAS_OP_SOLVE_MLP_LP_START: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { GNUNET_break(0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; ph.current_result->s_lp = GNUNET_TIME_absolute_get (); return; case GAS_OP_SOLVE_MLP_LP_STOP: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { GNUNET_break(0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; ph.current_result->e_lp = GNUNET_TIME_absolute_get (); ph.current_result->d_lp_full = GNUNET_TIME_absolute_get_difference ( ph.current_result->s_lp, ph.current_result->e_lp); return; case GAS_OP_SOLVE_MLP_MLP_START: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { GNUNET_break(0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; ph.current_result->s_mlp = GNUNET_TIME_absolute_get (); return; case GAS_OP_SOLVE_MLP_MLP_STOP: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result)) { GNUNET_break(0); return; } if (GAS_STAT_SUCCESS == stat) ph.current_result->valid = GNUNET_YES; else ph.current_result->valid = GNUNET_NO; ph.current_result->e_mlp = GNUNET_TIME_absolute_get (); ph.current_result->d_mlp_full = GNUNET_TIME_absolute_get_difference ( ph.current_result->s_mlp, ph.current_result->e_mlp); return; case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); return; case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP: GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP", (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL"); if (GAS_STAT_SUCCESS != stat) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Solver `%s' failed to update problem with %u peers and %u address!\n", ph.ats_string, ph.current_p, ph.current_a); } return; default: break; }
/** * This function updates the old token with new attributes, * removes deleted attributes and expiration times. * * @param cls the ego entry * @param tc task context */ static void handle_token_update (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { char *token_header; char *token_payload; char *token_payload_json; char *new_token; char *new_payload_str; char *new_payload_base64; char *sig_str; char *key; char *padding; const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; struct EgoEntry *ego_entry = cls; struct GNUNET_GNSRECORD_Data token_record; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; struct GNUNET_CRYPTO_EcdsaSignature sig; struct GNUNET_HashCode key_hash; struct GNUNET_TIME_Relative token_rel_exp; struct GNUNET_TIME_Relative token_ttl; struct GNUNET_TIME_Absolute token_exp; struct GNUNET_TIME_Absolute token_nbf; struct GNUNET_TIME_Absolute new_exp; struct GNUNET_TIME_Absolute new_iat; struct GNUNET_TIME_Absolute new_nbf; json_t *payload_json; json_t *value; json_t *cur_value; json_t *new_payload_json; json_t *token_nbf_json; json_t *token_exp_json; json_error_t json_err; priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); //Note: We need the token expiration time here. Not the record expiration //time. //There are two types of tokens: Token that expire on GNS level with //an absolute expiration time. Those are basically tokens that will //be automatically revoked on (record)expiration. //Tokens stored with relative expiration times will expire on the token level (token expiration) //but this service will reissue new tokens that can be retrieved from GNS //automatically. token_header = strtok (token, "."); token_payload = strtok (NULL, "."); GNUNET_STRINGS_base64_decode (token_payload, strlen (token_payload), &token_payload_json); payload_json = json_loads (token_payload_json, JSON_DECODE_ANY, &json_err); GNUNET_free (token_payload_json); token_exp_json = json_object_get (payload_json, "exp"); token_nbf_json = json_object_get (payload_json, "nbf"); token_exp.abs_value_us = json_integer_value(token_exp_json); token_nbf.abs_value_us = json_integer_value(token_nbf_json); token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp); token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp); if (0 != GNUNET_TIME_absolute_get_remaining (token_exp).rel_value_us) { //This token is not yet expired! Save and skip if (min_rel_exp.rel_value_us > token_ttl.rel_value_us) { min_rel_exp = token_ttl; } json_decref (payload_json); GNUNET_free (token); token = NULL; GNUNET_free (label); label = NULL; GNUNET_NAMESTORE_zone_iterator_next (ns_it); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Token is expired. Create a new one\n"); new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp); new_nbf = GNUNET_TIME_absolute_get (); new_iat = new_nbf; new_payload_json = json_object(); json_object_foreach(payload_json, key, value) { if (0 == strcmp (key, "exp")) { json_object_set_new (new_payload_json, key, json_integer (new_exp.abs_value_us)); } else if (0 == strcmp (key, "nbf")) { json_object_set_new (new_payload_json, key, json_integer (new_nbf.abs_value_us)); } else if (0 == strcmp (key, "iat")) { json_object_set_new (new_payload_json, key, json_integer (new_iat.abs_value_us)); } else if ((0 == strcmp (key, "iss")) || (0 == strcmp (key, "aud")) || (0 == strcmp (key, "sub")) || (0 == strcmp (key, "rnl"))) { json_object_set (new_payload_json, key, value); } else { GNUNET_CRYPTO_hash (key, strlen (key), &key_hash); //Check if attr still exists. omit of not if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map, &key_hash)) { cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map, &key_hash); json_object_set (new_payload_json, key, cur_value); } } } // reassemble and set new_payload_str = json_dumps (new_payload_json, JSON_COMPACT); json_decref (payload_json); json_decref (new_payload_json); GNUNET_STRINGS_base64_encode (new_payload_str, strlen (new_payload_str), &new_payload_base64); //Remove padding padding = strtok(new_payload_base64, "="); while (NULL != padding) padding = strtok(NULL, "="); GNUNET_asprintf (&new_token, "%s,%s", token_header, new_payload_base64); purpose = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (new_token)); purpose->size = htonl (strlen (new_token) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); memcpy (&purpose[1], new_token, strlen (new_token)); if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, purpose, &sig)) GNUNET_break(0); GNUNET_free (new_token); sig_str = GNUNET_STRINGS_data_to_string_alloc (&sig, sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); GNUNET_asprintf (&new_token, "%s.%s.%s", token_header, new_payload_base64, sig_str); GNUNET_free (sig_str); GNUNET_free (new_payload_str); GNUNET_free (new_payload_base64); GNUNET_free (purpose); token_record.data = new_token; token_record.data_size = strlen (new_token); token_record.expiration_time = new_exp.abs_value_us; token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; token_record.flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, priv_key, label, 1, &token_record, &store_token_cont, ego_entry); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token); GNUNET_free (new_token); GNUNET_free (token); token = NULL; GNUNET_free (label); label = NULL; }