2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * @file ats-tests/ats-testing-experiment.c
20 * @brief ats benchmark: controlled experiment execution
21 * @author Christian Grothoff
22 * @author Matthias Wachs
25 #include "gnunet_util_lib.h"
26 #include "gnunet-ats-solver-eval.h"
27 #include "gnunet-service-ats_normalization.h"
28 #include "gnunet-service-ats_preferences.c"
30 #define BIG_M_STRING "unlimited"
33 * Handle for statistics.
35 struct GNUNET_STATISTICS_Handle *GSA_stats;
38 static struct Experiment *e;
40 static struct LoggingHandle *l;
42 static struct SolverHandle *sh;
44 static struct TestPeer *peer_head;
46 static struct TestPeer *peer_tail;
48 static double default_properties[GNUNET_ATS_PropertyCount];
49 static double default_preferences[GNUNET_ATS_PreferenceCount];
52 * cmd option -e: experiment file
54 static char *opt_exp_file;
56 static char *opt_solver;
59 * cmd option -l: enable logging
64 * cmd option -p: enable plots
69 * cmd option -v: verbose logs
71 static int opt_verbose;
74 * cmd option -p: print logs
79 * cmd option -d: disable normalization
81 static int opt_disable_normalization;
90 print_generator_type (enum GeneratorType g)
93 case GNUNET_ATS_TEST_TG_CONSTANT:
95 case GNUNET_ATS_TEST_TG_LINEAR:
97 case GNUNET_ATS_TEST_TG_RANDOM:
99 case GNUNET_ATS_TEST_TG_SINUS:
108 static struct TestPeer *
109 find_peer_by_id (int id)
111 struct TestPeer *cur;
112 for (cur = peer_head; NULL != cur; cur = cur->next)
118 static struct TestPeer *
119 find_peer_by_pid (const struct GNUNET_PeerIdentity *pid)
121 struct TestPeer *cur;
122 for (cur = peer_head; NULL != cur; cur = cur->next)
123 if (0 == memcmp (&cur->peer_id, pid, sizeof (struct GNUNET_PeerIdentity)))
128 static struct TestAddress *
129 find_address_by_id (struct TestPeer *peer, int aid)
131 struct TestAddress *cur;
132 for (cur = peer->addr_head; NULL != cur; cur = cur->next)
143 GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
145 struct LoggingTimeStep *lts;
146 struct TestPeer *cur;
147 struct TestAddress *cur_addr;
148 struct LoggingPeer *log_p;
149 struct LoggingAddress *log_a;
152 lts = GNUNET_new (struct LoggingTimeStep);
153 GNUNET_CONTAINER_DLL_insert_tail(l->head, l->tail, lts);
154 lts->timestamp = GNUNET_TIME_absolute_get();
155 if (NULL == lts->prev)
156 lts->delta = GNUNET_TIME_UNIT_ZERO;
158 lts->delta = GNUNET_TIME_absolute_get_duration(lts->prev->timestamp);
160 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging %llu, delta %llu\n",
161 lts->timestamp.abs_value_us, lts->delta.rel_value_us);
164 /* Store logging data here */
165 for (cur = peer_head; NULL != cur; cur = cur->next)
167 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
168 "Logging peer id %llu\n", cur->id);
170 log_p = GNUNET_new (struct LoggingPeer);
172 log_p->peer_id = cur->peer_id;
173 log_p->is_requested = cur->is_requested;
174 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
176 log_p->pref_abs[c] = cur->pref_abs[c];
177 log_p->pref_norm[c] = cur->pref_norm[c];
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
179 "\t %s = %.2f %.2f [abs/rel]\n",
180 GNUNET_ATS_print_preference_type(c),
181 log_p->pref_abs[c], log_p->pref_norm[c]);
183 GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p);
185 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
187 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
188 "Logging peer id %llu address %llu\n",
189 cur->id, cur_addr->aid);
190 log_a = GNUNET_new (struct LoggingAddress);
191 log_a->aid = cur_addr->aid;
192 log_a->active = cur_addr->ats_addr->active;
193 log_a->network = cur_addr->network;
194 log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
195 log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
196 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
198 log_a->prop_abs[c] = cur_addr->prop_abs[c];
199 log_a->prop_norm[c] = cur_addr->prop_norm[c];
200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
201 "\t %s = %.2f %.2f [abs/rel]\n",
202 GNUNET_ATS_print_property_type(c),
204 log_a->prop_norm[c]);
206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in);
208 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "\t BW out = %llu\n", log_a->assigned_bw_out);
210 GNUNET_CONTAINER_DLL_insert_tail (log_p->addr_head, log_p->addr_tail, log_a);
217 logging_task (void *cls)
219 struct LoggingHandle *l = cls;
221 l->logging_task = NULL;
222 GNUNET_ATS_solver_logging_now (l);
223 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq,
228 struct LoggingHandle *
229 GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
231 struct LoggingHandle *l;
232 l = GNUNET_new (struct LoggingHandle);
234 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
235 GNUNET_STRINGS_relative_time_to_string(freq, GNUNET_NO));
237 l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
242 GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
244 if (NULL != l->logging_task)
245 GNUNET_SCHEDULER_cancel (l->logging_task);
247 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
249 l->logging_task = NULL;
252 static struct LoggingFileHandle *
253 find_logging_file_handle (struct LoggingFileHandle *lf_head,
254 struct LoggingFileHandle *lf_tail,
255 int peer_id, int address_id)
257 struct LoggingFileHandle *res;
259 for (res = lf_head; NULL != res; res = res->next)
260 if ((res->pid == peer_id) && (res->aid == address_id))
267 GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int add_time_stamp,
270 struct LoggingTimeStep *lts;
271 struct LoggingPeer *log_p;
272 struct LoggingAddress *log_a;
273 struct LoggingFileHandle *lf_head;
274 struct LoggingFileHandle *lf_tail;
275 struct LoggingFileHandle *cur;
276 struct LoggingFileHandle *next;
280 char * propstring_tmp;
282 char * prefstring_tmp;
287 if (NULL != output_dir)
289 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (output_dir))
291 fprintf (stderr, "Failed to create directory `%s'\n", output_dir);
296 fprintf (stderr, "Created directory `%s'\n", output_dir);
297 use_dir = GNUNET_YES;
304 for (lts = l->head; NULL != lts; lts = lts->next)
307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing log step %llu\n",
308 (long long unsigned int) lts->timestamp.abs_value_us);
310 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
312 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
315 cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
319 cur = GNUNET_new (struct LoggingFileHandle);
320 cur->aid = log_a->aid;
321 cur->pid = log_p->id;
323 if (GNUNET_YES == add_time_stamp)
324 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u_%llu.log",
325 (GNUNET_YES == use_dir) ? output_dir : "",
326 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
331 l->head->timestamp.abs_value_us);
333 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u.log",
334 (GNUNET_YES == use_dir) ? output_dir : "",
335 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
341 fprintf (stderr, "Add writing log data for peer %llu address %llu to file `%s'\n",
342 cur->pid, cur->aid, filename);
345 cur->f_hd = GNUNET_DISK_file_open (filename,
346 GNUNET_DISK_OPEN_READWRITE |
347 GNUNET_DISK_OPEN_CREATE |
348 GNUNET_DISK_OPEN_TRUNCATE,
349 GNUNET_DISK_PERM_USER_READ |
350 GNUNET_DISK_PERM_USER_WRITE |
351 GNUNET_DISK_PERM_GROUP_READ |
352 GNUNET_DISK_PERM_OTHER_READ);
353 if (NULL == cur->f_hd)
355 fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
356 GNUNET_free (filename);
360 GNUNET_free (filename);
361 GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
363 GNUNET_asprintf(&datastring,"#time delta;log duration;peer_requested;addr net; addr_active; bw in; bw out; " \
364 "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
365 "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;"\
367 "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
368 "COST_WLAN; COST_WLAN;COST_BT; COST_BT; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n");
369 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
370 GNUNET_free (datastring);
374 prefstring = GNUNET_strdup("");
375 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
378 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
379 GNUNET_ATS_print_preference_type(c),
380 log_p->pref_abs[c], log_p->pref_norm[c]);
382 GNUNET_asprintf(&prefstring_tmp,"%s;%.3f;%.3f",
383 prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
386 GNUNET_free (prefstring);
387 prefstring = GNUNET_strdup(prefstring_tmp);
388 GNUNET_free (prefstring_tmp);
392 propstring = GNUNET_strdup("");
393 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
395 if (GNUNET_ATS_NETWORK_TYPE == c)
398 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
399 GNUNET_ATS_print_property_type(c),
400 log_a->prop_abs[c], log_a->prop_norm[c]);*/
401 GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;",
404 log_a->prop_norm[c]);
405 GNUNET_free (propstring);
406 propstring = GNUNET_strdup(propstring_tmp);
407 GNUNET_free (propstring_tmp);
409 GNUNET_asprintf (&datastring, "%llu;%llu;%u;%u;%i;%u;%u;%s;%s\n",
410 GNUNET_TIME_absolute_get_difference (l->head->timestamp,
411 lts->timestamp).rel_value_us / 1000, lts->delta,
412 log_p->is_requested, log_a->network, log_a->active,
413 log_a->assigned_bw_in, log_a->assigned_bw_out, propstring,
416 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
417 GNUNET_free (datastring);
418 GNUNET_free (prefstring);
419 GNUNET_free (propstring);
426 for (cur = next; NULL != cur; cur = next)
429 GNUNET_CONTAINER_DLL_remove (lf_head, lf_tail, cur);
430 if (NULL != cur->f_hd)
431 GNUNET_DISK_file_close (cur->f_hd);
438 GNUNET_ATS_solver_logging_eval (struct LoggingHandle *l)
440 struct LoggingTimeStep *lts;
441 struct LoggingPeer *log_p;
442 struct LoggingAddress *log_a;
445 for (lts = l->head; NULL != lts; lts = lts->next)
447 fprintf (stderr, "Log step %llu %llu: \n",
448 (long long unsigned int) lts->timestamp.abs_value_us,
449 (long long unsigned int) lts->delta.rel_value_us);
451 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
453 fprintf (stderr,"\tLogging peer pid %llu\n", log_p->id);
454 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
456 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
457 GNUNET_ATS_print_preference_type(c),
458 log_p->pref_abs[c], log_p->pref_norm[c]);
461 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
463 fprintf (stderr, "\tPeer pid %llu address %llu: %u %u %u\n",
464 log_p->id, log_a->aid, log_a->active,
465 log_a->assigned_bw_in,
466 log_a->assigned_bw_out);
468 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
470 if (GNUNET_ATS_NETWORK_TYPE == c)
472 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
473 GNUNET_ATS_print_property_type(c),
474 log_a->prop_abs[c], log_a->prop_norm[c]);
482 GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
484 struct LoggingTimeStep *lts_cur;
485 struct LoggingTimeStep *lts_next;
486 struct LoggingPeer *log_p_cur;
487 struct LoggingPeer *log_p_next;
488 struct LoggingAddress *log_a_cur;
489 struct LoggingAddress *log_a_next;
491 if (NULL != l->logging_task)
492 GNUNET_SCHEDULER_cancel (l->logging_task);
493 l->logging_task = NULL;
496 while (NULL != (lts_cur = lts_next))
498 lts_next = lts_cur->next;
500 log_p_next = lts_cur->head;
501 while (NULL != (log_p_cur = log_p_next))
503 log_p_next = log_p_cur->next;
505 log_a_next = log_p_cur->addr_head;
506 while (NULL != (log_a_cur = log_a_next))
508 log_a_next = log_a_cur->next;
510 GNUNET_CONTAINER_DLL_remove (log_p_cur->addr_head, log_p_cur->addr_tail, log_a_cur);
511 GNUNET_free (log_a_cur);
514 GNUNET_CONTAINER_DLL_remove (lts_cur->head, lts_cur->tail, log_p_cur);
515 GNUNET_free (log_p_cur);
518 GNUNET_CONTAINER_DLL_remove (l->head, l->tail, lts_cur);
519 GNUNET_free (lts_cur);
526 * Property Generators
528 static struct PropertyGenerator *prop_gen_head;
529 static struct PropertyGenerator *prop_gen_tail;
533 get_property (struct PropertyGenerator *pg)
535 struct GNUNET_TIME_Relative time_delta;
539 /* Calculate the current preference value */
541 case GNUNET_ATS_TEST_TG_CONSTANT:
542 pref_value = pg->base_value;
544 case GNUNET_ATS_TEST_TG_LINEAR:
545 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
546 /* Calculate point of time in the current period */
547 time_delta.rel_value_us = time_delta.rel_value_us %
548 pg->duration_period.rel_value_us;
549 delta_value = ((double) time_delta.rel_value_us /
550 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
551 if ((pg->max_value < pg->base_value) &&
552 ((pg->max_value - pg->base_value) > pg->base_value))
554 /* This will cause an underflow */
557 pref_value = pg->base_value + delta_value;
559 case GNUNET_ATS_TEST_TG_RANDOM:
560 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
561 10000 * (pg->max_value - pg->base_value)) / 10000;
562 pref_value = pg->base_value + delta_value;
564 case GNUNET_ATS_TEST_TG_SINUS:
565 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
566 /* Calculate point of time in the current period */
567 time_delta.rel_value_us = time_delta.rel_value_us %
568 pg->duration_period.rel_value_us;
569 if ((pg->max_value - pg->base_value) > pg->base_value)
571 /* This will cause an underflow for second half of sinus period,
572 * will be detected in general when experiments are loaded */
575 delta_value = (pg->max_value - pg->base_value) *
576 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
577 time_delta.rel_value_us);
578 pref_value = pg->base_value + delta_value;
584 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current property value is %f\n",
591 set_prop_task (void *cls)
593 struct PropertyGenerator *pg = cls;
595 struct TestAddress *a;
597 struct GNUNET_ATS_Information atsi;
601 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains_value (sh->addresses,
602 &pg->test_peer->peer_id, pg->test_address->ats_addr))
605 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
606 "Setting property generation for unknown address [%u:%u]\n",
607 pg->peer, pg->address_id);
610 if (NULL == (p = find_peer_by_id (pg->peer)))
613 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
614 "Setting property generation for unknown peer %u\n",
618 if (NULL == (a = find_address_by_id (p, pg->address_id)))
621 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
622 "Setting property generation for unknown peer %u\n",
627 prop_value = get_property (pg);
628 a->prop_abs[pg->ats_property] = prop_value;
630 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
631 "Setting property for peer [%u] address [%u] for %s to %f\n",
632 pg->peer, pg->address_id,
633 GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
635 atsi.type = htonl (pg->ats_property);
636 atsi.value = htonl ((uint32_t) prop_value);
638 /* set performance here! */
639 sh->sf->s_bulk_start (sh->sf->cls);
640 if (GNUNET_YES == opt_disable_normalization)
642 a->prop_abs[pg->ats_property] = prop_value;
643 a->prop_norm[pg->ats_property] = prop_value;
644 sh->sf->s_address_update_property (sh->sf->cls, a->ats_addr,
645 pg->ats_property, prop_value, prop_value);
648 GAS_normalization_update_property (pg->test_address->ats_addr, &atsi, 1);
649 sh->sf->s_bulk_stop (sh->sf->cls);
651 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
657 * Set ats_property to 0 to find all pgs
659 static struct PropertyGenerator *
660 find_prop_gen (unsigned int peer, unsigned int address,
661 uint32_t ats_property)
663 struct PropertyGenerator *cur;
664 for (cur = prop_gen_head; NULL != cur; cur = cur->next)
665 if ((cur->peer == peer) && (cur->address_id == address))
667 if ((cur->ats_property == ats_property) || (0 == ats_property))
674 GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
676 GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
678 if (NULL != pg->set_task)
680 GNUNET_SCHEDULER_cancel (pg->set_task);
683 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
684 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
685 pg->peer, pg->address_id,
686 GNUNET_ATS_print_property_type(pg->ats_property));
693 * Generate between the source master and the partner and set property with a
694 * value depending on the generator.
697 * @param address_id partner
698 * @param test_peer the peer
699 * @param test_address the address
700 * @param type type of generator
701 * @param base_value base value
702 * @param value_rate maximum value
703 * @param period duration of a period of generation (~ 1/frequency)
704 * @param frequency how long to generate property
705 * @param ats_property ATS property to generate
706 * @return the property generator
708 struct PropertyGenerator *
709 GNUNET_ATS_solver_generate_property_start (unsigned int peer,
710 unsigned int address_id,
711 struct TestPeer *test_peer,
712 struct TestAddress *test_address,
713 enum GeneratorType type,
716 struct GNUNET_TIME_Relative period,
717 struct GNUNET_TIME_Relative frequency,
718 uint32_t ats_property)
720 struct PropertyGenerator *pg;
722 pg = GNUNET_new (struct PropertyGenerator);
723 GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
726 pg->test_address = test_address;
727 pg->test_peer = test_peer;
728 pg->address_id = address_id;
729 pg->ats_property = ats_property;
730 pg->base_value = base_value;
731 pg->max_value = value_rate;
732 pg->duration_period = period;
733 pg->frequency = frequency;
734 pg->time_start = GNUNET_TIME_absolute_get();
737 case GNUNET_ATS_TEST_TG_CONSTANT:
738 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
739 "Setting up %s property generator peer [%u] address [%u] `%s'"\
741 print_generator_type(type), pg->peer, pg->address_id,
742 GNUNET_ATS_print_property_type (ats_property),
745 case GNUNET_ATS_TEST_TG_LINEAR:
746 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
747 "Setting up %s property generator peer [%u] address [%u] `%s' " \
748 "min %u Bips max %u Bips\n",
749 print_generator_type(type), pg->peer, pg->address_id,
750 GNUNET_ATS_print_property_type(ats_property),
751 base_value, value_rate);
753 case GNUNET_ATS_TEST_TG_SINUS:
754 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
755 "Setting up %s property generator peer [%u] address [%u] `%s' "\
756 "baserate %u Bips, amplitude %u Bps\n",
757 print_generator_type(type), pg->peer, pg->address_id,
758 GNUNET_ATS_print_property_type(ats_property),
759 base_value, value_rate);
761 case GNUNET_ATS_TEST_TG_RANDOM:
762 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
763 "Setting up %s property generator peer [%u] address [%u] `%s' "\
764 "min %u Bips max %u Bps\n",
765 print_generator_type(type), pg->peer, pg->address_id,
766 GNUNET_ATS_print_property_type(ats_property),
767 base_value, value_rate);
773 pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
779 * Stop all preferences generators
782 GNUNET_ATS_solver_generate_property_stop_all ()
784 struct PropertyGenerator *cur;
785 struct PropertyGenerator *next;
786 next = prop_gen_head;
787 for (cur = next; NULL != cur; cur = next)
790 GNUNET_ATS_solver_generate_property_stop (cur);
796 * Preference Generators
798 static struct PreferenceGenerator *pref_gen_head;
799 static struct PreferenceGenerator *pref_gen_tail;
803 get_preference (struct PreferenceGenerator *pg)
805 struct GNUNET_TIME_Relative time_delta;
809 /* Calculate the current preference value */
811 case GNUNET_ATS_TEST_TG_CONSTANT:
812 pref_value = pg->base_value;
814 case GNUNET_ATS_TEST_TG_LINEAR:
815 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
816 /* Calculate point of time in the current period */
817 time_delta.rel_value_us = time_delta.rel_value_us %
818 pg->duration_period.rel_value_us;
819 delta_value = ((double) time_delta.rel_value_us /
820 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
821 if ((pg->max_value < pg->base_value) &&
822 ((pg->max_value - pg->base_value) > pg->base_value))
824 /* This will cause an underflow */
827 pref_value = pg->base_value + delta_value;
829 case GNUNET_ATS_TEST_TG_RANDOM:
830 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
831 10000 * (pg->max_value - pg->base_value)) / 10000;
832 pref_value = pg->base_value + delta_value;
834 case GNUNET_ATS_TEST_TG_SINUS:
835 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
836 /* Calculate point of time in the current period */
837 time_delta.rel_value_us = time_delta.rel_value_us %
838 pg->duration_period.rel_value_us;
839 if ((pg->max_value - pg->base_value) > pg->base_value)
841 /* This will cause an underflow for second half of sinus period,
842 * will be detected in general when experiments are loaded */
845 delta_value = (pg->max_value - pg->base_value) *
846 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
847 time_delta.rel_value_us);
848 pref_value = pg->base_value + delta_value;
854 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
861 set_feedback_task (void *cls)
863 struct PreferenceGenerator *pg = cls;
868 uint32_t delay_acc_in;
869 struct GNUNET_TIME_Relative dur;
872 pg->feedback_task = NULL;
874 if (NULL == (p = find_peer_by_id (pg->peer)))
877 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
878 "Setting feedback for unknown peer %u\n", pg->peer);
884 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
885 dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
886 bw_acc_in = dur.rel_value_us *pg->last_assigned_bw_in + pg->feedback_bw_in_acc;
887 pg->feedback_bw_in_acc = 0;
889 bw_acc_out = dur.rel_value_us *pg->last_assigned_bw_out + pg->feedback_bw_out_acc;
890 p_new = get_preference (pg);
891 feedback = (p_new / pg->pref_bw_old) * (bw_acc_in + bw_acc_out) /
892 (2 *GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
895 case GNUNET_ATS_PREFERENCE_LATENCY:
896 dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_delay_update);
897 delay_acc_in =dur.rel_value_us *pg->last_delay_value + pg->feedback_delay_acc;
898 pg->feedback_delay_acc = 0;
900 p_new = get_preference (pg);
901 feedback = (p_new / pg->pref_latency_old) * (delay_acc_in) /
902 (GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
910 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
911 "Giving feedback for peer [%u] for client %p pref %s of %.3f\n",
912 pg->peer, NULL + (pg->client_id),
913 GNUNET_ATS_print_preference_type (pg->kind),
916 sh->sf->s_feedback (sh->sf->cls, NULL + (pg->client_id), &p->peer_id,
917 pg->feedback_frequency, pg->kind, feedback);
918 pg->feedback_last = GNUNET_TIME_absolute_get();
921 pg->feedback_bw_out_acc = 0;
922 pg->feedback_bw_in_acc = 0;
923 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
925 pg->feedback_delay_acc = 0;
926 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
929 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (pg->feedback_frequency,
930 &set_feedback_task, pg);
935 set_pref_task (void *cls)
937 struct PreferenceGenerator *pg = cls;
942 if (NULL == (p = find_peer_by_id (pg->peer)))
945 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
946 "Setting preference for unknown peer %u\n", pg->peer);
950 pref_value = get_preference (pg);
952 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
953 pg->pref_bw_old = pref_value;
955 case GNUNET_ATS_PREFERENCE_LATENCY:
956 pg->pref_latency_old = pref_value;
962 p->pref_abs[pg->kind] = pref_value;
964 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
965 "Setting preference for peer [%u] for client %p pref %s to %f\n",
966 pg->peer, NULL + (pg->client_id),
967 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
969 if (GNUNET_YES == opt_disable_normalization)
971 p->pref_abs[pg->kind] = pref_value;
972 p->pref_norm[pg->kind] = pref_value;
973 sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
976 update_preference (NULL + (pg->client_id),
981 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
987 static struct PreferenceGenerator *
988 find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
990 struct PreferenceGenerator *cur;
991 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
992 if (cur->peer == peer)
994 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
1001 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
1003 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
1005 if (NULL != pg->feedback_task)
1007 GNUNET_SCHEDULER_cancel (pg->feedback_task);
1008 pg->feedback_task = NULL;
1011 if (NULL != pg->set_task)
1013 GNUNET_SCHEDULER_cancel (pg->set_task);
1014 pg->set_task = NULL;
1016 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1017 "Removing old up preference generator peer [%u] `%s'\n",
1018 pg->peer, GNUNET_ATS_print_preference_type(pg->kind));
1024 static struct TestAddress*
1025 find_active_address (struct TestPeer *p)
1027 struct TestAddress *cur;
1028 for (cur = p->addr_head; NULL != cur; cur = cur->next)
1029 if (GNUNET_YES == cur->ats_addr->active)
1036 * Generate between the source master and the partner and set property with a
1037 * value depending on the generator.
1039 * @param peer source
1040 * @param address_id partner
1041 * @param client_id the client
1042 * @param type type of generator
1043 * @param base_value base value
1044 * @param value_rate maximum value
1045 * @param period duration of a period of generation (~ 1/frequency)
1046 * @param frequency how long to generate property
1047 * @param kind ATS preference to generate
1048 * @param feedback_frequency how often to give feedback
1049 * @return the preference generator
1051 struct PreferenceGenerator *
1052 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
1053 unsigned int address_id,
1054 unsigned int client_id,
1055 enum GeneratorType type,
1056 long int base_value,
1057 long int value_rate,
1058 struct GNUNET_TIME_Relative period,
1059 struct GNUNET_TIME_Relative frequency,
1060 enum GNUNET_ATS_PreferenceKind kind,
1061 struct GNUNET_TIME_Relative feedback_frequency)
1063 struct PreferenceGenerator *pg;
1066 if (NULL == (p = find_peer_by_id (peer)))
1069 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1070 "Starting preference for unknown peer %u\n", peer);
1074 pg = GNUNET_new (struct PreferenceGenerator);
1075 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
1078 pg->client_id = client_id;
1080 pg->base_value = base_value;
1081 pg->max_value = value_rate;
1082 pg->duration_period = period;
1083 pg->frequency = frequency;
1084 pg->time_start = GNUNET_TIME_absolute_get();
1085 pg->feedback_frequency = feedback_frequency;
1088 case GNUNET_ATS_TEST_TG_CONSTANT:
1089 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1090 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
1091 print_generator_type (type), pg->peer,
1092 GNUNET_ATS_print_preference_type(kind),
1095 case GNUNET_ATS_TEST_TG_LINEAR:
1096 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1097 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
1098 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1099 base_value, value_rate);
1101 case GNUNET_ATS_TEST_TG_SINUS:
1102 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1103 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
1104 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1105 base_value, value_rate);
1107 case GNUNET_ATS_TEST_TG_RANDOM:
1108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1109 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1110 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1111 base_value, value_rate);
1117 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1118 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != feedback_frequency.rel_value_us)
1120 struct TestAddress * addr = find_active_address(p);
1122 pg->last_assigned_bw_in = p->assigned_bw_in;
1123 pg->last_assigned_bw_out = p->assigned_bw_out;
1124 pg->feedback_bw_in_acc = 0;
1125 pg->feedback_bw_out_acc = 0;
1126 pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
1127 pg->feedback_delay_acc = 0;
1129 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
1130 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
1131 pg->feedback_last = GNUNET_TIME_absolute_get();
1132 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
1133 &set_feedback_task, pg);
1142 * Stop all preferences generators
1145 GNUNET_ATS_solver_generate_preferences_stop_all ()
1147 struct PreferenceGenerator *cur;
1148 struct PreferenceGenerator *next;
1149 next = pref_gen_head;
1150 for (cur = next; NULL != cur; cur = next)
1153 GNUNET_ATS_solver_generate_preferences_stop(cur);
1163 print_op (enum OperationType op)
1166 case SOLVER_OP_ADD_ADDRESS:
1167 return "ADD_ADDRESS";
1168 case SOLVER_OP_DEL_ADDRESS:
1169 return "DEL_ADDRESS";
1170 case SOLVER_OP_START_SET_PREFERENCE:
1171 return "START_SET_PREFERENCE";
1172 case SOLVER_OP_STOP_SET_PREFERENCE:
1173 return "STOP_STOP_PREFERENCE";
1174 case SOLVER_OP_START_SET_PROPERTY:
1175 return "START_SET_PROPERTY";
1176 case SOLVER_OP_STOP_SET_PROPERTY:
1177 return "STOP_SET_PROPERTY";
1178 case SOLVER_OP_START_REQUEST:
1179 return "START_REQUEST";
1180 case SOLVER_OP_STOP_REQUEST:
1181 return "STOP_REQUEST";
1189 static struct Experiment *
1190 create_experiment ()
1192 struct Experiment *e;
1193 e = GNUNET_new (struct Experiment);
1196 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1202 free_experiment (struct Experiment *e)
1204 struct Episode *cur;
1205 struct Episode *next;
1206 struct GNUNET_ATS_TEST_Operation *cur_o;
1207 struct GNUNET_ATS_TEST_Operation *next_o;
1210 for (cur = next; NULL != cur; cur = next)
1215 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1217 next_o = cur_o->next;
1218 GNUNET_free_non_null (cur_o->address);
1219 GNUNET_free_non_null (cur_o->plugin);
1220 GNUNET_free (cur_o);
1225 GNUNET_free_non_null (e->name);
1226 GNUNET_free_non_null (e->log_prefix);
1227 GNUNET_free_non_null (e->log_output_dir);
1228 GNUNET_free_non_null (e->cfg_file);
1234 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1238 const struct GNUNET_CONFIGURATION_Handle *cfg)
1244 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1245 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1246 sec_name, op_name, &o->peer_id))
1248 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1249 op_counter, "ADD_ADDRESS", op_name);
1250 GNUNET_free (op_name);
1251 return GNUNET_SYSERR;
1253 GNUNET_free (op_name);
1256 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1257 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1258 sec_name, op_name, &o->address_id))
1260 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1261 op_counter, "ADD_ADDRESS", op_name);
1262 GNUNET_free (op_name);
1263 return GNUNET_SYSERR;
1265 GNUNET_free (op_name);
1268 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1269 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1270 sec_name, op_name, &o->plugin))
1272 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1273 op_counter, "ADD_ADDRESS", op_name);
1274 GNUNET_free (op_name);
1275 return GNUNET_SYSERR;
1277 GNUNET_free (op_name);
1280 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1281 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1282 sec_name, op_name, &o->address))
1284 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1285 op_counter, "ADD_ADDRESS", op_name);
1286 GNUNET_free (op_name);
1287 return GNUNET_SYSERR;
1289 GNUNET_free (op_name);
1292 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1293 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1294 sec_name, op_name, &o->address_session))
1296 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1297 op_counter, "ADD_ADDRESS", op_name);
1298 GNUNET_free (op_name);
1299 return GNUNET_SYSERR;
1301 GNUNET_free (op_name);
1304 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
1305 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1306 sec_name, op_name, &op_network))
1308 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
1309 op_counter, "ADD_ADDRESS", op_name);
1310 GNUNET_free (op_name);
1311 return GNUNET_SYSERR;
1315 GNUNET_STRINGS_utf8_toupper (op_network,op_network);
1316 if (0 == strcmp(op_network, "UNSPECIFIED"))
1318 o->address_network = GNUNET_ATS_NET_UNSPECIFIED;
1320 else if (0 == strcmp(op_network, "LOOPBACK"))
1322 o->address_network = GNUNET_ATS_NET_LOOPBACK;
1324 else if (0 == strcmp(op_network, "LAN"))
1326 o->address_network = GNUNET_ATS_NET_LAN;
1328 else if (0 == strcmp(op_network, "WAN"))
1330 o->address_network = GNUNET_ATS_NET_WAN;
1332 else if (0 == strcmp(op_network, "WLAN"))
1334 o->address_network = GNUNET_ATS_NET_WLAN;
1336 else if (0 == strcmp(op_network, "BT"))
1338 o->address_network = GNUNET_ATS_NET_BT;
1342 fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1343 op_counter, "ADD_ADDRESS", op_name, op_network);
1344 GNUNET_free (op_network);
1345 GNUNET_free (op_name);
1346 return GNUNET_SYSERR;
1349 GNUNET_free (op_network);
1350 GNUNET_free (op_name);
1352 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1353 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1354 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1361 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1365 const struct GNUNET_CONFIGURATION_Handle *cfg)
1371 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1372 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1373 sec_name, op_name, &o->peer_id))
1375 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1376 op_counter, "DEL_ADDRESS", op_name);
1377 GNUNET_free (op_name);
1378 return GNUNET_SYSERR;
1380 GNUNET_free (op_name);
1383 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1384 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1385 sec_name, op_name, &o->address_id))
1387 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1388 op_counter, "DEL_ADDRESS", op_name);
1389 GNUNET_free (op_name);
1390 return GNUNET_SYSERR;
1392 GNUNET_free (op_name);
1396 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1397 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1398 sec_name, op_name, &o->plugin))
1400 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1401 op_counter, "DEL_ADDRESS", op_name);
1402 GNUNET_free (op_name);
1403 return GNUNET_SYSERR;
1405 GNUNET_free (op_name);
1408 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1409 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1410 sec_name, op_name, &o->address))
1412 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1413 op_counter, "DEL_ADDRESS", op_name);
1414 GNUNET_free (op_name);
1415 return GNUNET_SYSERR;
1417 GNUNET_free (op_name);
1420 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1421 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1422 sec_name, op_name, &o->address_session))
1424 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1425 op_counter, "DEL_ADDRESS", op_name);
1426 GNUNET_free (op_name);
1427 return GNUNET_SYSERR;
1429 GNUNET_free (op_name);
1432 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1433 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1434 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1440 static enum GNUNET_ATS_Property
1441 parse_preference_string (const char * str)
1444 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1446 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1447 if (0 == strcmp(str, props[c]))
1454 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1458 const struct GNUNET_CONFIGURATION_Handle *cfg)
1465 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1466 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1467 sec_name, op_name, &o->peer_id))
1469 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1470 op_counter, "START_SET_PREFERENCE", op_name);
1471 GNUNET_free (op_name);
1472 return GNUNET_SYSERR;
1474 GNUNET_free (op_name);
1477 GNUNET_asprintf(&op_name, "op-%u-client-id", op_counter);
1478 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1479 sec_name, op_name, &o->client_id))
1481 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1482 op_counter, "START_SET_PREFERENCE", op_name);
1483 GNUNET_free (op_name);
1484 return GNUNET_SYSERR;
1486 GNUNET_free (op_name);
1489 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1490 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1491 sec_name, op_name, &type)) )
1493 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1494 op_counter, "START_SET_PREFERENCE", op_name);
1495 GNUNET_free (op_name);
1496 return GNUNET_SYSERR;
1499 /* Load arguments for set_rate, start_send, set_preference */
1500 if (0 == strcmp (type, "constant"))
1502 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1504 else if (0 == strcmp (type, "linear"))
1506 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1508 else if (0 == strcmp (type, "sinus"))
1510 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1512 else if (0 == strcmp (type, "random"))
1514 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1518 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1519 op_counter, op_name, e->id);
1521 GNUNET_free (op_name);
1522 return GNUNET_SYSERR;
1525 GNUNET_free (op_name);
1529 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1530 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1531 sec_name, op_name, &o->base_rate))
1533 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1534 op_counter, op_name, e->id);
1535 GNUNET_free (op_name);
1536 return GNUNET_SYSERR;
1538 GNUNET_free (op_name);
1542 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1543 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1544 sec_name, op_name, &o->max_rate))
1546 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1547 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1548 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1550 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1551 op_counter, op_name, e->id);
1552 GNUNET_free (op_name);
1553 return GNUNET_SYSERR;
1556 GNUNET_free (op_name);
1559 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1560 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1561 sec_name, op_name, &o->period))
1563 o->period = e->duration;
1565 GNUNET_free (op_name);
1568 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1569 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1570 sec_name, op_name, &o->frequency))
1572 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1573 op_counter, op_name, e->id);
1574 GNUNET_free (op_name);
1575 return GNUNET_SYSERR;
1577 GNUNET_free (op_name);
1579 /* Get preference */
1580 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1581 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1582 sec_name, op_name, &pref))
1584 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1585 op_counter, op_name, e->id);
1586 GNUNET_free (op_name);
1587 return GNUNET_SYSERR;
1590 if (0 == (o->pref_type = parse_preference_string(pref)))
1592 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1593 op_counter, op_name, e->id);
1594 GNUNET_free (op_name);
1596 return GNUNET_SYSERR;
1599 GNUNET_free (op_name);
1601 /* Get feedback delay */
1602 GNUNET_asprintf(&op_name, "op-%u-feedback_delay", op_counter);
1603 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
1604 sec_name, op_name, &o->feedback_delay))
1606 fprintf (stderr, "Using feedback delay %llu in operation %u `%s' in episode %u\n",
1607 (long long unsigned int) o->feedback_delay.rel_value_us,
1608 op_counter, op_name, e->id);
1611 o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
1612 GNUNET_free (op_name);
1614 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1615 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1616 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1617 GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
1624 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1628 const struct GNUNET_CONFIGURATION_Handle *cfg)
1634 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1635 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1636 sec_name, op_name, &o->peer_id))
1638 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1639 op_counter, "STOP_SET_PREFERENCE", op_name);
1640 GNUNET_free (op_name);
1641 return GNUNET_SYSERR;
1643 GNUNET_free (op_name);
1646 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1647 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1648 sec_name, op_name, &o->address_id))
1650 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1651 op_counter, "STOP_SET_PREFERENCE", op_name);
1652 GNUNET_free (op_name);
1653 return GNUNET_SYSERR;
1655 GNUNET_free (op_name);
1657 /* Get preference */
1658 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1659 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1660 sec_name, op_name, &pref))
1662 fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
1663 op_counter, "STOP_SET_PREFERENCE", op_name);
1664 GNUNET_free (op_name);
1665 return GNUNET_SYSERR;
1668 if (0 == (o->pref_type = parse_preference_string(pref)))
1670 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1671 op_counter, op_name, e->id);
1672 GNUNET_free (op_name);
1674 return GNUNET_SYSERR;
1677 GNUNET_free (op_name);
1679 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1680 "Found operation %s: [%llu:%llu]: %s\n",
1681 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1682 GNUNET_ATS_print_preference_type(o->pref_type));
1687 static enum GNUNET_ATS_Property
1688 parse_property_string (const char *str)
1690 enum GNUNET_ATS_Property c;
1692 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1693 if (0 == strcmp(str,
1694 GNUNET_ATS_print_property_type (c)))
1701 load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
1705 const struct GNUNET_CONFIGURATION_Handle *cfg)
1712 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1713 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1714 sec_name, op_name, &o->peer_id))
1716 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1717 op_counter, "START_SET_PROPERTY", op_name);
1718 GNUNET_free (op_name);
1719 return GNUNET_SYSERR;
1721 GNUNET_free (op_name);
1724 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1725 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1726 sec_name, op_name, &o->address_id))
1728 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1729 op_counter, "START_SET_PROPERTY", op_name);
1730 GNUNET_free (op_name);
1731 return GNUNET_SYSERR;
1733 GNUNET_free (op_name);
1736 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1737 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1738 sec_name, op_name, &type)) )
1740 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1741 op_counter, "START_SET_PROPERTY", op_name);
1742 GNUNET_free (op_name);
1743 return GNUNET_SYSERR;
1746 /* Load arguments for set_rate, start_send, set_preference */
1747 if (0 == strcmp (type, "constant"))
1749 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1751 else if (0 == strcmp (type, "linear"))
1753 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1755 else if (0 == strcmp (type, "sinus"))
1757 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1759 else if (0 == strcmp (type, "random"))
1761 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1765 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1766 op_counter, op_name, e->id);
1768 GNUNET_free (op_name);
1769 return GNUNET_SYSERR;
1772 GNUNET_free (op_name);
1776 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1777 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1778 sec_name, op_name, &o->base_rate))
1780 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1781 op_counter, op_name, e->id);
1782 GNUNET_free (op_name);
1783 return GNUNET_SYSERR;
1785 GNUNET_free (op_name);
1789 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1790 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1791 sec_name, op_name, &o->max_rate))
1793 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1794 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1795 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1797 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1798 op_counter, op_name, e->id);
1799 GNUNET_free (op_name);
1800 return GNUNET_SYSERR;
1803 GNUNET_free (op_name);
1806 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1807 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1808 sec_name, op_name, &o->period))
1810 o->period = e->duration;
1812 GNUNET_free (op_name);
1815 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1816 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1817 sec_name, op_name, &o->frequency))
1819 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1820 op_counter, op_name, e->id);
1821 GNUNET_free (op_name);
1822 return GNUNET_SYSERR;
1824 GNUNET_free (op_name);
1826 /* Get preference */
1827 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1828 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1829 sec_name, op_name, &prop))
1831 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1832 op_counter, op_name, e->id);
1833 GNUNET_free (op_name);
1834 GNUNET_free_non_null (prop);
1835 return GNUNET_SYSERR;
1838 if (0 == (o->prop_type = parse_property_string(prop)))
1840 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1841 op_counter, op_name, e->id);
1842 GNUNET_free (op_name);
1844 return GNUNET_SYSERR;
1848 GNUNET_free (op_name);
1850 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1851 "Found operation %s: [%llu:%llu] %s = %llu\n",
1852 "START_SET_PROPERTY", o->peer_id, o->address_id,
1853 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1859 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1863 const struct GNUNET_CONFIGURATION_Handle *cfg)
1869 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1870 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1871 sec_name, op_name, &o->peer_id))
1873 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1874 op_counter, "STOP_SET_PROPERTY", op_name);
1875 GNUNET_free (op_name);
1876 return GNUNET_SYSERR;
1878 GNUNET_free (op_name);
1881 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1882 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1883 sec_name, op_name, &o->address_id))
1885 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1886 op_counter, "STOP_SET_PROPERTY", op_name);
1887 GNUNET_free (op_name);
1888 return GNUNET_SYSERR;
1890 GNUNET_free (op_name);
1893 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1894 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1895 sec_name, op_name, &pref))
1897 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
1898 op_counter, "STOP_SET_PROPERTY", op_name);
1899 GNUNET_free (op_name);
1900 GNUNET_free_non_null (pref);
1901 return GNUNET_SYSERR;
1904 if (0 == (o->prop_type = parse_property_string(pref)))
1906 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1907 op_counter, op_name, e->id);
1908 GNUNET_free (op_name);
1909 GNUNET_free_non_null (pref);
1910 return GNUNET_SYSERR;
1914 GNUNET_free (op_name);
1916 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1917 "Found operation %s: [%llu:%llu] %s\n",
1918 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
1919 GNUNET_ATS_print_property_type (o->prop_type));
1926 load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
1930 const struct GNUNET_CONFIGURATION_Handle *cfg)
1935 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1936 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1937 sec_name, op_name, &o->peer_id))
1939 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1940 op_counter, "START_REQUEST", op_name);
1941 GNUNET_free (op_name);
1942 return GNUNET_SYSERR;
1944 GNUNET_free (op_name);
1949 load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
1953 const struct GNUNET_CONFIGURATION_Handle *cfg)
1958 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1959 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1960 sec_name, op_name, &o->peer_id))
1962 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1963 op_counter, "STOP_REQUEST", op_name);
1964 GNUNET_free (op_name);
1965 return GNUNET_SYSERR;
1967 GNUNET_free (op_name);
1973 load_episode (struct Experiment *e, struct Episode *cur,
1974 struct GNUNET_CONFIGURATION_Handle *cfg)
1976 struct GNUNET_ATS_TEST_Operation *o;
1982 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n",cur->id);
1983 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
1987 /* Load operation */
1988 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
1989 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1990 sec_name, op_name, &op))
1992 GNUNET_free (op_name);
1995 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
1996 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
1999 /* operations = set_rate, start_send, stop_send, set_preference */
2000 if (0 == strcmp (op, "address_add"))
2002 o->type = SOLVER_OP_ADD_ADDRESS;
2003 res = load_op_add_address (o, cur,
2004 op_counter, sec_name, cfg);
2006 else if (0 == strcmp (op, "address_del"))
2008 o->type = SOLVER_OP_DEL_ADDRESS;
2009 res = load_op_del_address (o, cur,
2010 op_counter, sec_name, cfg);
2012 else if (0 == strcmp (op, "start_set_property"))
2014 o->type = SOLVER_OP_START_SET_PROPERTY;
2015 res = load_op_start_set_property (o, cur,
2016 op_counter, sec_name, cfg);
2018 else if (0 == strcmp (op, "stop_set_property"))
2020 o->type = SOLVER_OP_STOP_SET_PROPERTY;
2021 res = load_op_stop_set_property (o, cur,
2022 op_counter, sec_name, cfg);
2024 else if (0 == strcmp (op, "start_set_preference"))
2026 o->type = SOLVER_OP_START_SET_PREFERENCE;
2027 res = load_op_start_set_preference (o, cur,
2028 op_counter, sec_name, cfg);
2030 else if (0 == strcmp (op, "stop_set_preference"))
2032 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
2033 res = load_op_stop_set_preference (o, cur,
2034 op_counter, sec_name, cfg);
2036 else if (0 == strcmp (op, "start_request"))
2038 o->type = SOLVER_OP_START_REQUEST;
2039 res = load_op_start_request (o, cur,
2040 op_counter, sec_name, cfg);
2042 else if (0 == strcmp (op, "stop_request"))
2044 o->type = SOLVER_OP_STOP_REQUEST;
2045 res = load_op_stop_request(o, cur,
2046 op_counter, sec_name, cfg);
2050 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
2051 op_counter, op, cur->id);
2052 res = GNUNET_SYSERR;
2056 GNUNET_free (op_name);
2058 if (GNUNET_SYSERR == res)
2061 GNUNET_free (sec_name);
2062 return GNUNET_SYSERR;
2065 GNUNET_CONTAINER_DLL_insert_tail (cur->head,cur->tail, o);
2068 GNUNET_free (sec_name);
2073 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
2077 struct GNUNET_TIME_Relative e_duration;
2078 struct Episode *cur;
2079 struct Episode *last;
2085 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
2086 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
2087 sec_name, "duration", &e_duration))
2089 GNUNET_free (sec_name);
2093 cur = GNUNET_new (struct Episode);
2094 cur->duration = e_duration;
2095 cur->id = e_counter;
2097 if (GNUNET_OK != load_episode (e, cur, cfg))
2099 GNUNET_free (sec_name);
2101 return GNUNET_SYSERR;
2104 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2106 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
2108 /* Update experiment */
2110 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
2111 /* Put in linked list */
2117 GNUNET_free (sec_name);
2126 timeout_experiment (void *cls)
2128 struct Experiment *e = cls;
2130 e->experiment_timeout_task = NULL;
2131 fprintf (stderr, "Experiment timeout!\n");
2133 if (NULL != e->episode_timeout_task)
2135 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2136 e->episode_timeout_task = NULL;
2139 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
2143 struct ATS_Address *
2144 create_ats_address (const struct GNUNET_PeerIdentity *peer,
2145 const char *plugin_name,
2146 const void *plugin_addr,
2147 size_t plugin_addr_len,
2148 uint32_t session_id,
2151 struct ATS_Address *aa = NULL;
2153 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len + strlen (plugin_name) + 1);
2154 aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
2155 aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
2156 aa->atsi[0].value = htonl (network);
2160 aa->addr_len = plugin_addr_len;
2162 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2163 GNUNET_memcpy (&aa[1], plugin_addr, plugin_addr_len);
2164 GNUNET_memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2165 aa->session_id = session_id;
2173 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2176 struct TestAddress *a;
2179 if (NULL == (p = find_peer_by_id (op->peer_id)))
2181 p = GNUNET_new (struct TestPeer);
2182 p->id = op->peer_id;
2183 p->assigned_bw_in = 0;
2184 p->assigned_bw_out = 0;
2185 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2186 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2188 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2189 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2192 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2195 if (NULL != (find_address_by_id (p, op->address_id)))
2197 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2198 op->address_id, op->peer_id);
2202 a = GNUNET_new (struct TestAddress);
2203 a->aid = op->address_id;
2204 a->network = op->address_network;
2205 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2206 strlen (op->address) + 1, op->address_session, op->address_network);
2207 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2208 GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
2210 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2211 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2213 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2214 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2216 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding address %u for peer %u in network `%s'\n",
2217 op->address_id, op->peer_id, GNUNET_ATS_print_network_type(a->network));
2219 sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
2225 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2228 struct TestAddress *a;
2229 struct PropertyGenerator *pg;
2231 if (NULL == (p = find_peer_by_id (op->peer_id)))
2234 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2235 "Deleting address for unknown peer %u\n", op->peer_id);
2239 if (NULL == (a =find_address_by_id (p, op->address_id)))
2242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2243 "Deleting address for unknown peer %u\n", op->peer_id);
2247 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2249 GNUNET_ATS_solver_generate_property_stop (pg);
2252 GNUNET_assert (GNUNET_YES ==
2253 GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
2256 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2257 "Removing address %u for peer %u\n",
2261 sh->sf->s_del (sh->sf->cls, a->ats_addr);
2265 GNUNET_ATS_solver_logging_now (l);
2267 GNUNET_CONTAINER_DLL_remove(p->addr_head, p->addr_tail, a);
2269 GNUNET_free_non_null(a->ats_addr->atsi);
2270 GNUNET_free (a->ats_addr);
2276 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2278 struct PropertyGenerator *pg;
2280 struct TestAddress *a;
2282 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2284 GNUNET_ATS_solver_generate_property_stop (pg);
2288 if (NULL == (p = find_peer_by_id (op->peer_id)))
2291 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2292 "Starting property generation for unknown peer %u\n", op->peer_id);
2296 if (NULL == (a = find_address_by_id (p, op->address_id)))
2299 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2300 "Setting property for unknown address %u\n", op->peer_id);
2304 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2316 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2318 struct PropertyGenerator *pg = find_prop_gen(op->peer_id, op->address_id,
2322 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2323 "Stopping preference generation for peer %u address %u\n", op->peer_id,
2325 GNUNET_ATS_solver_generate_property_stop (pg);
2329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2330 "Cannot find preference generator for peer %u address %u\n",
2331 op->peer_id, op->address_id);
2337 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2339 struct PreferenceGenerator *pg;
2340 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2342 GNUNET_ATS_solver_generate_preferences_stop (pg);
2346 if (NULL == (find_peer_by_id (op->peer_id)))
2349 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2350 "Starting preference generation for unknown peer %u\n", op->peer_id);
2354 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2367 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2369 struct PreferenceGenerator *pg = find_pref_gen(op->peer_id,
2373 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2374 "Stopping property generation for peer %u address %u\n", op->peer_id,
2376 GNUNET_ATS_solver_generate_preferences_stop (pg);
2380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2381 "Cannot find preference generator for peer %u address %u\n",
2382 op->peer_id, op->address_id);
2389 enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2393 if (NULL == (p = find_peer_by_id (op->peer_id)))
2396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2397 "Requesting address for unknown peer %u\n", op->peer_id);
2401 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2403 p->is_requested = GNUNET_YES;
2405 sh->sf->s_get (sh->sf->cls, &p->peer_id);
2410 enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
2414 if (NULL == (p = find_peer_by_id (op->peer_id)))
2417 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2418 "Requesting address for unknown peer %u\n", op->peer_id);
2422 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2423 "Stop requesting address for peer %u\n",
2425 p->is_requested = GNUNET_NO;
2426 p->assigned_bw_in = 0;
2427 p->assigned_bw_out = 0;
2428 sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
2432 GNUNET_ATS_solver_logging_now (l);
2437 static void enforce_episode (struct Episode *ep)
2439 struct GNUNET_ATS_TEST_Operation *cur;
2440 for (cur = ep->head; NULL != cur; cur = cur->next)
2442 switch (cur->type) {
2443 case SOLVER_OP_ADD_ADDRESS:
2444 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2445 print_op (cur->type), cur->peer_id, cur->address_id);
2446 enforce_add_address (cur);
2448 case SOLVER_OP_DEL_ADDRESS:
2449 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2450 print_op (cur->type), cur->peer_id, cur->address_id);
2451 enforce_del_address (cur);
2453 case SOLVER_OP_START_SET_PROPERTY:
2454 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2455 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2456 enforce_start_property (cur);
2458 case SOLVER_OP_STOP_SET_PROPERTY:
2459 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2460 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2461 enforce_stop_property (cur);
2463 case SOLVER_OP_START_SET_PREFERENCE:
2464 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2465 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2466 enforce_start_preference (cur);
2468 case SOLVER_OP_STOP_SET_PREFERENCE:
2469 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2470 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2471 enforce_stop_preference (cur);
2473 case SOLVER_OP_START_REQUEST:
2474 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2475 print_op (cur->type), cur->peer_id);
2476 enforce_start_request (cur);
2478 case SOLVER_OP_STOP_REQUEST:
2479 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2480 print_op (cur->type), cur->peer_id);
2481 enforce_stop_request (cur);
2491 timeout_episode (void *cls)
2493 struct Experiment *e = cls;
2495 e->episode_timeout_task = NULL;
2496 if (NULL != e->ep_done_cb)
2497 e->ep_done_cb (e->cur);
2499 /* Scheduling next */
2500 e->cur = e->cur->next;
2504 fprintf (stderr, "Last episode done!\n");
2505 if (NULL != e->experiment_timeout_task)
2507 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2508 e->experiment_timeout_task = NULL;
2510 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
2514 fprintf (stderr, "Running episode %u with timeout %s\n",
2516 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2517 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2518 &timeout_episode, e);
2519 enforce_episode(e->cur);
2526 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2527 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
2528 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
2530 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2531 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
2532 e->e_done_cb = e_done_cb;
2533 e->ep_done_cb = ep_done_cb;
2534 e->start_time = GNUNET_TIME_absolute_get();
2536 /* Start total time out */
2537 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2538 &timeout_experiment, e);
2541 if (NULL == e->start)
2548 fprintf (stderr, "Running episode %u with timeout %s\n",
2550 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2551 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2552 &timeout_episode, e);
2553 enforce_episode(e->cur);
2558 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2560 if (NULL != e->experiment_timeout_task)
2562 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2563 e->experiment_timeout_task = NULL;
2565 if (NULL != e->episode_timeout_task)
2567 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2568 e->episode_timeout_task = NULL;
2572 GNUNET_CONFIGURATION_destroy(e->cfg);
2575 free_experiment (e);
2580 GNUNET_ATS_solvers_experimentation_load (char *filename)
2582 struct Experiment *e;
2583 struct GNUNET_CONFIGURATION_Handle *cfg;
2586 cfg = GNUNET_CONFIGURATION_create();
2587 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2589 fprintf (stderr, "Failed to load `%s'\n", filename);
2590 GNUNET_CONFIGURATION_destroy (cfg);
2594 e = create_experiment ();
2596 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2599 fprintf (stderr, "Invalid %s \n", "name");
2600 free_experiment (e);
2604 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2606 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2607 "log_prefix", &e->log_prefix))
2609 fprintf (stderr, "Invalid %s \n", "log_prefix");
2610 free_experiment (e);
2614 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2617 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2618 "log_output_dir", &e->log_output_dir))
2620 e->log_output_dir = NULL;
2623 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging output directory: `%s'\n",
2627 if (GNUNET_SYSERR == (e->log_append_time_stamp = GNUNET_CONFIGURATION_get_value_yesno(cfg,
2628 "experiment", "log_append_time_stamp")))
2629 e->log_append_time_stamp = GNUNET_YES;
2630 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging append timestamp: `%s'\n",
2631 (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
2634 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2635 "cfg_file", &e->cfg_file))
2637 fprintf (stderr, "Invalid %s \n", "cfg_file");
2638 free_experiment (e);
2643 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n", e->cfg_file);
2644 e->cfg = GNUNET_CONFIGURATION_create();
2645 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2647 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2648 free_experiment (e);
2654 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2655 "log_freq", &e->log_freq))
2657 fprintf (stderr, "Invalid %s \n", "log_freq");
2658 free_experiment (e);
2662 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2663 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
2665 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2666 "max_duration", &e->max_duration))
2668 fprintf (stderr, "Invalid %s", "max_duration");
2669 free_experiment (e);
2673 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2674 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
2676 if (GNUNET_SYSERR == load_episodes (e, cfg))
2678 GNUNET_ATS_solvers_experimentation_stop (e);
2679 GNUNET_CONFIGURATION_destroy (cfg);
2681 fprintf (stderr, "Failed to load experiment\n");
2684 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded %u episodes with total duration %s\n",
2686 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
2688 GNUNET_CONFIGURATION_destroy (cfg);
2699 free_all_it (void *cls,
2700 const struct GNUNET_PeerIdentity *key,
2703 struct ATS_Address *address = value;
2704 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (sh->env.addresses,
2706 GNUNET_free (address);
2712 GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2714 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2716 GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
2718 GAS_normalization_stop();
2720 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
2723 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
2724 GNUNET_free (sh->plugin);
2730 * Load quotas for networks from configuration
2732 * @param cfg configuration handle
2733 * @param out_dest where to write outbound quotas
2734 * @param in_dest where to write inbound quotas
2735 * @param dest_length length of inbound and outbound arrays
2736 * @return number of networks loaded
2739 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2740 unsigned long long *out_dest,
2741 unsigned long long *in_dest,
2744 char * entry_in = NULL;
2745 char * entry_out = NULL;
2746 char * quota_out_str;
2747 char * quota_in_str;
2751 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
2755 GNUNET_asprintf (&entry_out,
2757 GNUNET_ATS_print_network_type (c));
2758 GNUNET_asprintf (&entry_in,
2760 GNUNET_ATS_print_network_type (c));
2763 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
2766 if (0 == strcmp(quota_out_str, BIG_M_STRING))
2768 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2771 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
2773 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
2776 if (GNUNET_NO == res)
2778 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2779 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2780 GNUNET_ATS_print_network_type (c),
2782 GNUNET_ATS_DefaultBandwidth);
2783 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2788 "Outbound quota configure for network `%s' is %llu\n",
2789 GNUNET_ATS_print_network_type (c),
2792 GNUNET_free (quota_out_str);
2796 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2797 _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
2798 GNUNET_ATS_print_network_type (c),
2799 GNUNET_ATS_DefaultBandwidth);
2800 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2804 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
2807 if (0 == strcmp(quota_in_str, BIG_M_STRING))
2809 in_dest[c] = GNUNET_ATS_MaxBandwidth;
2812 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
2814 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
2817 if (GNUNET_NO == res)
2819 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2820 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2821 GNUNET_ATS_print_network_type (c),
2823 GNUNET_ATS_DefaultBandwidth);
2824 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
2828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2829 "Inbound quota configured for network `%s' is %llu\n",
2830 GNUNET_ATS_print_network_type (c),
2833 GNUNET_free (quota_in_str);
2837 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2838 _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
2839 GNUNET_ATS_print_network_type (c),
2840 GNUNET_ATS_DefaultBandwidth);
2841 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2843 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2844 "Loaded quota for network `%s' (in/out): %llu %llu\n",
2845 GNUNET_ATS_print_network_type (c),
2848 GNUNET_free (entry_out);
2849 GNUNET_free (entry_in);
2851 return GNUNET_ATS_NetworkTypeCount;
2856 * Information callback for the solver
2858 * @param cls the closure
2859 * @param op the solver operation
2860 * @param stat status of the solver operation
2861 * @param add additional solver information
2864 solver_info_cb (void *cls,
2865 enum GAS_Solver_Operation op,
2866 enum GAS_Solver_Status stat,
2867 enum GAS_Solver_Additional_Information add)
2872 add_info = "GAS_INFO_NONE";
2875 add_info = "GAS_INFO_MLP_FULL";
2877 case GAS_INFO_UPDATED:
2878 add_info = "GAS_INFO_MLP_UPDATED";
2880 case GAS_INFO_PROP_ALL:
2881 add_info = "GAS_INFO_PROP_ALL";
2883 case GAS_INFO_PROP_SINGLE:
2884 add_info = "GAS_INFO_PROP_SINGLE";
2887 add_info = "INVALID";
2893 case GAS_OP_SOLVE_START:
2894 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2895 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
2896 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2898 case GAS_OP_SOLVE_STOP:
2899 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2900 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
2901 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2904 case GAS_OP_SOLVE_SETUP_START:
2905 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2906 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
2907 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2910 case GAS_OP_SOLVE_SETUP_STOP:
2911 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2912 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
2913 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2916 case GAS_OP_SOLVE_MLP_LP_START:
2917 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2918 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
2919 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2921 case GAS_OP_SOLVE_MLP_LP_STOP:
2922 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2923 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
2924 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2927 case GAS_OP_SOLVE_MLP_MLP_START:
2928 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2929 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
2930 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2932 case GAS_OP_SOLVE_MLP_MLP_STOP:
2933 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2934 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
2935 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2937 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
2938 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2939 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
2940 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2942 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
2943 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2944 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
2945 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2953 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
2955 struct GNUNET_TIME_Relative duration;
2957 static struct PreferenceGenerator *pg;
2959 if ( (0 == address->assigned_bw_out) && (0 == address->assigned_bw_in) )
2961 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2962 "Solver notified to disconnect peer `%s'\n",
2963 GNUNET_i2s (&address->peer));
2965 p = find_peer_by_pid(&address->peer);
2968 p->assigned_bw_out = address->assigned_bw_out;
2969 p->assigned_bw_in = address->assigned_bw_in;
2971 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
2973 if (pg->peer == p->id)
2975 duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
2976 delta = duration.rel_value_us * pg->last_assigned_bw_out;
2977 pg->feedback_bw_out_acc += delta;
2979 delta = duration.rel_value_us * pg->last_assigned_bw_in;
2980 pg->feedback_bw_in_acc += delta;
2982 pg->last_assigned_bw_in = address->assigned_bw_in;
2983 pg->last_assigned_bw_out = address->assigned_bw_out;
2984 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
2988 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2989 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
2990 GNUNET_i2s (&address->peer),
2992 address->assigned_bw_out,
2993 address->assigned_bw_in);
2996 GNUNET_ATS_solver_logging_now (l);
3002 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3005 if (GNUNET_YES == opt_disable_normalization)
3007 if (NULL == (p = find_peer_by_pid (id)))
3012 return GAS_preference_get_by_peer (NULL,
3017 struct SolverHandle *
3018 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3020 struct SolverHandle *sh;
3024 case GNUNET_ATS_SOLVER_PROPORTIONAL:
3025 solver_str = "proportional";
3027 case GNUNET_ATS_SOLVER_MLP:
3030 case GNUNET_ATS_SOLVER_RIL:
3039 sh = GNUNET_new (struct SolverHandle);
3040 GNUNET_asprintf (&sh->plugin,
3041 "libgnunet_plugin_ats_%s",
3043 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
3045 /* setup environment */
3046 sh->env.cfg = e->cfg;
3047 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
3048 sh->env.addresses = sh->addresses;
3049 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
3050 sh->env.get_preferences = &get_preferences_cb;
3051 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
3052 sh->env.info_cb = &solver_info_cb;
3053 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
3055 /* start normalization */
3056 GAS_normalization_start ();
3059 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
3060 sh->env.out_quota, sh->env.in_quota, GNUNET_ATS_NetworkTypeCount))
3063 GNUNET_free (sh->plugin);
3069 sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
3072 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
3074 GNUNET_free (sh->plugin);
3086 struct TestPeer *cur;
3087 struct TestPeer *next;
3089 struct TestAddress *cur_a;
3090 struct TestAddress *next_a;
3093 GNUNET_ATS_solver_logging_stop (l);
3095 /* Stop all preference generation */
3096 GNUNET_ATS_solver_generate_preferences_stop_all ();
3098 /* Stop all property generation */
3099 GNUNET_ATS_solver_generate_property_stop_all ();
3103 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
3104 GNUNET_ATS_solver_logging_eval (l);
3108 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
3109 GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
3115 GNUNET_ATS_solver_logging_free (l);
3119 /* Clean up experiment */
3122 GNUNET_ATS_solvers_experimentation_stop (e);
3127 while (NULL != (cur = next))
3130 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3131 next_a = cur->addr_head;
3132 while (NULL != (cur_a = next_a))
3134 next_a = cur_a->next;
3135 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3136 GNUNET_free (cur_a);
3142 GNUNET_ATS_solvers_solver_stop (sh);
3151 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
3153 if (GNUNET_OK == success)
3154 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3155 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3157 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3159 GNUNET_SCHEDULER_add_now (&done, NULL);
3163 episode_done_cb (struct Episode *ep)
3165 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3178 GNUNET_ATS_solvers_experimentation_stop (e);
3183 GNUNET_ATS_solvers_solver_stop (sh);
3189 run (void *cls, char * const *args, const char *cfgfile,
3190 const struct GNUNET_CONFIGURATION_Handle *cfg)
3192 enum GNUNET_ATS_Solvers solver;
3195 if (NULL == opt_exp_file)
3197 fprintf (stderr, "No experiment given ...\n");
3203 if (NULL == opt_solver)
3205 fprintf (stderr, "No solver given ...\n");
3211 if (0 == strcmp(opt_solver, "mlp"))
3213 solver = GNUNET_ATS_SOLVER_MLP;
3215 else if (0 == strcmp(opt_solver, "proportional"))
3217 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3219 else if (0 == strcmp(opt_solver, "ril"))
3221 solver = GNUNET_ATS_SOLVER_RIL;
3225 fprintf (stderr, "No solver given ...");
3231 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3232 default_properties[c] = DEFAULT_REL_QUALITY;
3234 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3235 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3237 /* load experiment */
3238 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3239 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3242 fprintf (stderr, "Failed to load experiment ...\n");
3249 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3250 sh = GNUNET_ATS_solvers_solver_start (solver);
3253 fprintf (stderr, "Failed to start solver ...\n");
3260 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3261 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3263 /* run experiment */
3264 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3265 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3266 experiment_done_cb);
3273 * Main function of the benchmark
3275 * @param argc argument count
3276 * @param argv argument values
3279 main (int argc, char *argv[])
3281 opt_exp_file = NULL;
3283 opt_log = GNUNET_NO;
3284 opt_save = GNUNET_NO;
3288 static struct GNUNET_GETOPT_CommandLineOption options[] =
3290 GNUNET_GETOPT_option_string ('s',
3292 gettext_noop ("solver to use"),
3295 GNUNET_GETOPT_option_string ('e',
3297 gettext_noop ("experiment to use"),
3300 GNUNET_GETOPT_option_verbose (&opt_verbose),
3302 GNUNET_GETOPT_option_flag ('p',
3304 gettext_noop ("print logging"),
3307 GNUNET_GETOPT_option_flag ('f',
3309 gettext_noop ("save logging to disk"),
3312 GNUNET_GETOPT_option_flag ('d',
3314 gettext_noop ("disable normalization"),
3315 &opt_disable_normalization),
3317 GNUNET_GETOPT_OPTION_END
3320 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3321 NULL, options, &run, argv[0]);
3325 /* end of file ats-testing-experiment.c*/