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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
27 #include "gnunet_util_lib.h"
28 #include "gnunet-ats-solver-eval.h"
29 #include "gnunet-service-ats_normalization.h"
30 #include "gnunet-service-ats_preferences.c"
32 #define BIG_M_STRING "unlimited"
35 * Handle for statistics.
37 struct GNUNET_STATISTICS_Handle *GSA_stats;
40 static struct Experiment *e;
42 static struct LoggingHandle *l;
44 static struct SolverHandle *sh;
46 static struct TestPeer *peer_head;
48 static struct TestPeer *peer_tail;
50 static double default_properties[GNUNET_ATS_PropertyCount];
51 static double default_preferences[GNUNET_ATS_PreferenceCount];
54 * cmd option -e: experiment file
56 static char *opt_exp_file;
58 static char *opt_solver;
61 * cmd option -l: enable logging
66 * cmd option -p: enable plots
71 * cmd option -v: verbose logs
73 static int opt_verbose;
76 * cmd option -p: print logs
81 * cmd option -d: disable normalization
83 static int opt_disable_normalization;
92 print_generator_type (enum GeneratorType g)
96 case GNUNET_ATS_TEST_TG_CONSTANT:
99 case GNUNET_ATS_TEST_TG_LINEAR:
102 case GNUNET_ATS_TEST_TG_RANDOM:
105 case GNUNET_ATS_TEST_TG_SINUS:
115 static struct TestPeer *
116 find_peer_by_id (int id)
118 struct TestPeer *cur;
120 for (cur = peer_head; NULL != cur; cur = cur->next)
126 static struct TestPeer *
127 find_peer_by_pid (const struct GNUNET_PeerIdentity *pid)
129 struct TestPeer *cur;
131 for (cur = peer_head; NULL != cur; cur = cur->next)
132 if (0 == GNUNET_memcmp (&cur->peer_id, pid))
137 static struct TestAddress *
138 find_address_by_id (struct TestPeer *peer, int aid)
140 struct TestAddress *cur;
142 for (cur = peer->addr_head; NULL != cur; cur = cur->next)
153 GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
155 struct LoggingTimeStep *lts;
156 struct TestPeer *cur;
157 struct TestAddress *cur_addr;
158 struct LoggingPeer *log_p;
159 struct LoggingAddress *log_a;
162 lts = GNUNET_new (struct LoggingTimeStep);
163 GNUNET_CONTAINER_DLL_insert_tail (l->head, l->tail, lts);
164 lts->timestamp = GNUNET_TIME_absolute_get ();
165 if (NULL == lts->prev)
166 lts->delta = GNUNET_TIME_UNIT_ZERO;
168 lts->delta = GNUNET_TIME_absolute_get_duration (lts->prev->timestamp);
170 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging %llu, delta %llu\n",
171 lts->timestamp.abs_value_us, lts->delta.rel_value_us);
174 /* Store logging data here */
175 for (cur = peer_head; NULL != cur; cur = cur->next)
177 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
178 "Logging peer id %llu\n", cur->id);
180 log_p = GNUNET_new (struct LoggingPeer);
182 log_p->peer_id = cur->peer_id;
183 log_p->is_requested = cur->is_requested;
184 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
186 log_p->pref_abs[c] = cur->pref_abs[c];
187 log_p->pref_norm[c] = cur->pref_norm[c];
188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
189 "\t %s = %.2f %.2f [abs/rel]\n",
190 GNUNET_ATS_print_preference_type (c),
191 log_p->pref_abs[c], log_p->pref_norm[c]);
193 GNUNET_CONTAINER_DLL_insert_tail (lts->head, lts->tail, log_p);
195 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
197 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
198 "Logging peer id %llu address %llu\n",
199 cur->id, cur_addr->aid);
200 log_a = GNUNET_new (struct LoggingAddress);
201 log_a->aid = cur_addr->aid;
202 log_a->active = cur_addr->ats_addr->active;
203 log_a->network = cur_addr->network;
204 log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
205 log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
206 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
208 log_a->prop_abs[c] = cur_addr->prop_abs[c];
209 log_a->prop_norm[c] = cur_addr->prop_norm[c];
210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
211 "\t %s = %.2f %.2f [abs/rel]\n",
212 GNUNET_ATS_print_property_type (c),
214 log_a->prop_norm[c]);
216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n",
218 log_a->assigned_bw_in);
219 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "\t BW out = %llu\n",
220 log_a->assigned_bw_out);
222 GNUNET_CONTAINER_DLL_insert_tail (log_p->addr_head, log_p->addr_tail,
230 logging_task (void *cls)
232 struct LoggingHandle *l = cls;
234 l->logging_task = NULL;
235 GNUNET_ATS_solver_logging_now (l);
236 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq,
241 struct LoggingHandle *
242 GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
244 struct LoggingHandle *l;
246 l = GNUNET_new (struct LoggingHandle);
248 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
249 GNUNET_STRINGS_relative_time_to_string (freq, GNUNET_NO));
251 l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
256 GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
258 if (NULL != l->logging_task)
259 GNUNET_SCHEDULER_cancel (l->logging_task);
261 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
263 l->logging_task = NULL;
266 static struct LoggingFileHandle *
267 find_logging_file_handle (struct LoggingFileHandle *lf_head,
268 struct LoggingFileHandle *lf_tail,
269 int peer_id, int address_id)
271 struct LoggingFileHandle *res;
273 for (res = lf_head; NULL != res; res = res->next)
274 if ((res->pid == peer_id) && (res->aid == address_id))
280 GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int
284 struct LoggingTimeStep *lts;
285 struct LoggingPeer *log_p;
286 struct LoggingAddress *log_a;
287 struct LoggingFileHandle *lf_head;
288 struct LoggingFileHandle *lf_tail;
289 struct LoggingFileHandle *cur;
290 struct LoggingFileHandle *next;
294 char *propstring_tmp;
296 char *prefstring_tmp;
301 if (NULL != output_dir)
303 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (output_dir))
305 fprintf (stderr, "Failed to create directory `%s'\n", output_dir);
310 fprintf (stderr, "Created directory `%s'\n", output_dir);
311 use_dir = GNUNET_YES;
318 for (lts = l->head; NULL != lts; lts = lts->next)
320 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing log step %llu\n",
321 (long long unsigned int) lts->timestamp.abs_value_us);
323 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
325 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
327 cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
331 cur = GNUNET_new (struct LoggingFileHandle);
332 cur->aid = log_a->aid;
333 cur->pid = log_p->id;
335 if (GNUNET_YES == add_time_stamp)
336 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u_%llu.log",
337 (GNUNET_YES == use_dir) ? output_dir : "",
338 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
343 l->head->timestamp.abs_value_us);
345 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u.log",
346 (GNUNET_YES == use_dir) ? output_dir : "",
347 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
354 "Add writing log data for peer %llu address %llu to file `%s'\n",
355 cur->pid, cur->aid, filename);
358 cur->f_hd = GNUNET_DISK_file_open (filename,
359 GNUNET_DISK_OPEN_READWRITE
360 | GNUNET_DISK_OPEN_CREATE
361 | GNUNET_DISK_OPEN_TRUNCATE,
362 GNUNET_DISK_PERM_USER_READ
363 | GNUNET_DISK_PERM_USER_WRITE
364 | GNUNET_DISK_PERM_GROUP_READ
365 | GNUNET_DISK_PERM_OTHER_READ);
366 if (NULL == cur->f_hd)
368 fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
369 GNUNET_free (filename);
373 GNUNET_free (filename);
374 GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
376 GNUNET_asprintf (&datastring,
377 "#time delta;log duration;peer_requested;addr net; addr_active; bw in; bw out; " \
378 "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
379 "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;" \
381 "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
382 "COST_WLAN; COST_WLAN;COST_BT; COST_BT; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n");
383 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen (datastring));
384 GNUNET_free (datastring);
387 prefstring = GNUNET_strdup ("");
388 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
391 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
392 GNUNET_ATS_print_preference_type(c),
393 log_p->pref_abs[c], log_p->pref_norm[c]);
395 GNUNET_asprintf (&prefstring_tmp, "%s;%.3f;%.3f",
396 prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
399 GNUNET_free (prefstring);
400 prefstring = GNUNET_strdup (prefstring_tmp);
401 GNUNET_free (prefstring_tmp);
405 propstring = GNUNET_strdup ("");
406 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
408 if (GNUNET_ATS_NETWORK_TYPE == c)
411 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
412 GNUNET_ATS_print_property_type(c),
413 log_a->prop_abs[c], log_a->prop_norm[c]);*/
414 GNUNET_asprintf (&propstring_tmp, "%s%.3f;%.3f;",
417 log_a->prop_norm[c]);
418 GNUNET_free (propstring);
419 propstring = GNUNET_strdup (propstring_tmp);
420 GNUNET_free (propstring_tmp);
422 GNUNET_asprintf (&datastring, "%llu;%llu;%u;%u;%i;%u;%u;%s;%s\n",
423 GNUNET_TIME_absolute_get_difference (
426 rel_value_us / 1000, lts->delta,
427 log_p->is_requested, log_a->network, log_a->active,
428 log_a->assigned_bw_in, log_a->assigned_bw_out,
432 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen (datastring));
433 GNUNET_free (datastring);
434 GNUNET_free (prefstring);
435 GNUNET_free (propstring);
442 for (cur = next; NULL != cur; cur = next)
445 GNUNET_CONTAINER_DLL_remove (lf_head, lf_tail, cur);
446 if (NULL != cur->f_hd)
447 GNUNET_DISK_file_close (cur->f_hd);
453 GNUNET_ATS_solver_logging_eval (struct LoggingHandle *l)
455 struct LoggingTimeStep *lts;
456 struct LoggingPeer *log_p;
457 struct LoggingAddress *log_a;
460 for (lts = l->head; NULL != lts; lts = lts->next)
462 fprintf (stderr, "Log step %llu %llu: \n",
463 (long long unsigned int) lts->timestamp.abs_value_us,
464 (long long unsigned int) lts->delta.rel_value_us);
466 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
468 fprintf (stderr, "\tLogging peer pid %llu\n", log_p->id);
469 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
471 fprintf (stderr, "\t %s = %.2f %.2f [abs/rel]\n",
472 GNUNET_ATS_print_preference_type (c),
473 log_p->pref_abs[c], log_p->pref_norm[c]);
476 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
478 fprintf (stderr, "\tPeer pid %llu address %llu: %u %u %u\n",
479 log_p->id, log_a->aid, log_a->active,
480 log_a->assigned_bw_in,
481 log_a->assigned_bw_out);
483 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
485 if (GNUNET_ATS_NETWORK_TYPE == c)
487 fprintf (stderr, "\t %s = %.2f %.2f [abs/rel]\n",
488 GNUNET_ATS_print_property_type (c),
489 log_a->prop_abs[c], log_a->prop_norm[c]);
497 GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
499 struct LoggingTimeStep *lts_cur;
500 struct LoggingTimeStep *lts_next;
501 struct LoggingPeer *log_p_cur;
502 struct LoggingPeer *log_p_next;
503 struct LoggingAddress *log_a_cur;
504 struct LoggingAddress *log_a_next;
506 if (NULL != l->logging_task)
507 GNUNET_SCHEDULER_cancel (l->logging_task);
508 l->logging_task = NULL;
511 while (NULL != (lts_cur = lts_next))
513 lts_next = lts_cur->next;
515 log_p_next = lts_cur->head;
516 while (NULL != (log_p_cur = log_p_next))
518 log_p_next = log_p_cur->next;
520 log_a_next = log_p_cur->addr_head;
521 while (NULL != (log_a_cur = log_a_next))
523 log_a_next = log_a_cur->next;
525 GNUNET_CONTAINER_DLL_remove (log_p_cur->addr_head, log_p_cur->addr_tail,
527 GNUNET_free (log_a_cur);
530 GNUNET_CONTAINER_DLL_remove (lts_cur->head, lts_cur->tail, log_p_cur);
531 GNUNET_free (log_p_cur);
534 GNUNET_CONTAINER_DLL_remove (l->head, l->tail, lts_cur);
535 GNUNET_free (lts_cur);
542 * Property Generators
544 static struct PropertyGenerator *prop_gen_head;
545 static struct PropertyGenerator *prop_gen_tail;
549 get_property (struct PropertyGenerator *pg)
551 struct GNUNET_TIME_Relative time_delta;
555 /* Calculate the current preference value */
558 case GNUNET_ATS_TEST_TG_CONSTANT:
559 pref_value = pg->base_value;
562 case GNUNET_ATS_TEST_TG_LINEAR:
563 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
564 /* Calculate point of time in the current period */
565 time_delta.rel_value_us = time_delta.rel_value_us
566 % pg->duration_period.rel_value_us;
567 delta_value = ((double) time_delta.rel_value_us
568 / pg->duration_period.rel_value_us) * (pg->max_value
570 if ((pg->max_value < pg->base_value) &&
571 ((pg->max_value - pg->base_value) > pg->base_value))
573 /* This will cause an underflow */
576 pref_value = pg->base_value + delta_value;
579 case GNUNET_ATS_TEST_TG_RANDOM:
580 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
581 10000 * (pg->max_value
584 pref_value = pg->base_value + delta_value;
587 case GNUNET_ATS_TEST_TG_SINUS:
588 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
589 /* Calculate point of time in the current period */
590 time_delta.rel_value_us = time_delta.rel_value_us
591 % pg->duration_period.rel_value_us;
592 if ((pg->max_value - pg->base_value) > pg->base_value)
594 /* This will cause an underflow for second half of sinus period,
595 * will be detected in general when experiments are loaded */
598 delta_value = (pg->max_value - pg->base_value)
600 / ((double) pg->duration_period.rel_value_us)
601 * time_delta.rel_value_us);
602 pref_value = pg->base_value + delta_value;
609 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current property value is %f\n",
616 set_prop_task (void *cls)
618 struct PropertyGenerator *pg = cls;
620 struct TestAddress *a;
622 struct GNUNET_ATS_Information atsi;
626 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains_value (sh->addresses,
634 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
635 "Setting property generation for unknown address [%u:%u]\n",
636 pg->peer, pg->address_id);
639 if (NULL == (p = find_peer_by_id (pg->peer)))
642 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
643 "Setting property generation for unknown peer %u\n",
647 if (NULL == (a = find_address_by_id (p, pg->address_id)))
650 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
651 "Setting property generation for unknown peer %u\n",
656 prop_value = get_property (pg);
657 a->prop_abs[pg->ats_property] = prop_value;
659 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
660 "Setting property for peer [%u] address [%u] for %s to %f\n",
661 pg->peer, pg->address_id,
662 GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
664 atsi.type = htonl (pg->ats_property);
665 atsi.value = htonl ((uint32_t) prop_value);
667 /* set performance here! */
668 sh->sf->s_bulk_start (sh->sf->cls);
669 if (GNUNET_YES == opt_disable_normalization)
671 a->prop_abs[pg->ats_property] = prop_value;
672 a->prop_norm[pg->ats_property] = prop_value;
673 sh->sf->s_address_update_property (sh->sf->cls, a->ats_addr,
674 pg->ats_property, prop_value,
678 GAS_normalization_update_property (pg->test_address->ats_addr, &atsi, 1);
679 sh->sf->s_bulk_stop (sh->sf->cls);
681 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
687 * Set ats_property to 0 to find all pgs
689 static struct PropertyGenerator *
690 find_prop_gen (unsigned int peer, unsigned int address,
691 uint32_t ats_property)
693 struct PropertyGenerator *cur;
695 for (cur = prop_gen_head; NULL != cur; cur = cur->next)
696 if ((cur->peer == peer) && (cur->address_id == address))
698 if ((cur->ats_property == ats_property) || (0 == ats_property))
705 GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
707 GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
709 if (NULL != pg->set_task)
711 GNUNET_SCHEDULER_cancel (pg->set_task);
714 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
715 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
716 pg->peer, pg->address_id,
717 GNUNET_ATS_print_property_type (pg->ats_property));
724 * Generate between the source master and the partner and set property with a
725 * value depending on the generator.
728 * @param address_id partner
729 * @param test_peer the peer
730 * @param test_address the address
731 * @param type type of generator
732 * @param base_value base value
733 * @param value_rate maximum value
734 * @param period duration of a period of generation (~ 1/frequency)
735 * @param frequency how long to generate property
736 * @param ats_property ATS property to generate
737 * @return the property generator
739 struct PropertyGenerator *
740 GNUNET_ATS_solver_generate_property_start (unsigned int peer,
741 unsigned int address_id,
742 struct TestPeer *test_peer,
743 struct TestAddress *test_address,
744 enum GeneratorType type,
747 struct GNUNET_TIME_Relative period,
748 struct GNUNET_TIME_Relative
750 uint32_t ats_property)
752 struct PropertyGenerator *pg;
754 pg = GNUNET_new (struct PropertyGenerator);
755 GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
758 pg->test_address = test_address;
759 pg->test_peer = test_peer;
760 pg->address_id = address_id;
761 pg->ats_property = ats_property;
762 pg->base_value = base_value;
763 pg->max_value = value_rate;
764 pg->duration_period = period;
765 pg->frequency = frequency;
766 pg->time_start = GNUNET_TIME_absolute_get ();
770 case GNUNET_ATS_TEST_TG_CONSTANT:
771 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
772 "Setting up %s property generator peer [%u] address [%u] `%s'" \
774 print_generator_type (type), pg->peer, pg->address_id,
775 GNUNET_ATS_print_property_type (ats_property),
779 case GNUNET_ATS_TEST_TG_LINEAR:
780 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
781 "Setting up %s property generator peer [%u] address [%u] `%s' " \
782 "min %u Bips max %u Bips\n",
783 print_generator_type (type), pg->peer, pg->address_id,
784 GNUNET_ATS_print_property_type (ats_property),
785 base_value, value_rate);
788 case GNUNET_ATS_TEST_TG_SINUS:
789 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
790 "Setting up %s property generator peer [%u] address [%u] `%s' " \
791 "baserate %u Bips, amplitude %u Bps\n",
792 print_generator_type (type), pg->peer, pg->address_id,
793 GNUNET_ATS_print_property_type (ats_property),
794 base_value, value_rate);
797 case GNUNET_ATS_TEST_TG_RANDOM:
798 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
799 "Setting up %s property generator peer [%u] address [%u] `%s' " \
800 "min %u Bips max %u Bps\n",
801 print_generator_type (type), pg->peer, pg->address_id,
802 GNUNET_ATS_print_property_type (ats_property),
803 base_value, value_rate);
810 pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
816 * Stop all preferences generators
819 GNUNET_ATS_solver_generate_property_stop_all ()
821 struct PropertyGenerator *cur;
822 struct PropertyGenerator *next;
824 next = prop_gen_head;
825 for (cur = next; NULL != cur; cur = next)
828 GNUNET_ATS_solver_generate_property_stop (cur);
834 * Preference Generators
836 static struct PreferenceGenerator *pref_gen_head;
837 static struct PreferenceGenerator *pref_gen_tail;
841 get_preference (struct PreferenceGenerator *pg)
843 struct GNUNET_TIME_Relative time_delta;
847 /* Calculate the current preference value */
850 case GNUNET_ATS_TEST_TG_CONSTANT:
851 pref_value = pg->base_value;
854 case GNUNET_ATS_TEST_TG_LINEAR:
855 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
856 /* Calculate point of time in the current period */
857 time_delta.rel_value_us = time_delta.rel_value_us
858 % pg->duration_period.rel_value_us;
859 delta_value = ((double) time_delta.rel_value_us
860 / pg->duration_period.rel_value_us) * (pg->max_value
862 if ((pg->max_value < pg->base_value) &&
863 ((pg->max_value - pg->base_value) > pg->base_value))
865 /* This will cause an underflow */
868 pref_value = pg->base_value + delta_value;
871 case GNUNET_ATS_TEST_TG_RANDOM:
872 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
873 10000 * (pg->max_value
876 pref_value = pg->base_value + delta_value;
879 case GNUNET_ATS_TEST_TG_SINUS:
880 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
881 /* Calculate point of time in the current period */
882 time_delta.rel_value_us = time_delta.rel_value_us
883 % pg->duration_period.rel_value_us;
884 if ((pg->max_value - pg->base_value) > pg->base_value)
886 /* This will cause an underflow for second half of sinus period,
887 * will be detected in general when experiments are loaded */
890 delta_value = (pg->max_value - pg->base_value)
892 / ((double) pg->duration_period.rel_value_us)
893 * time_delta.rel_value_us);
894 pref_value = pg->base_value + delta_value;
901 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
908 set_feedback_task (void *cls)
910 struct PreferenceGenerator *pg = cls;
915 uint32_t delay_acc_in;
916 struct GNUNET_TIME_Relative dur;
919 pg->feedback_task = NULL;
921 if (NULL == (p = find_peer_by_id (pg->peer)))
924 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
925 "Setting feedback for unknown peer %u\n", pg->peer);
931 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
932 dur = GNUNET_TIME_absolute_get_duration (pg->feedback_last_bw_update);
933 bw_acc_in = dur.rel_value_us * pg->last_assigned_bw_in
934 + pg->feedback_bw_in_acc;
935 pg->feedback_bw_in_acc = 0;
937 bw_acc_out = dur.rel_value_us * pg->last_assigned_bw_out
938 + pg->feedback_bw_out_acc;
939 p_new = get_preference (pg);
940 feedback = (p_new / pg->pref_bw_old) * (bw_acc_in + bw_acc_out)
941 / (2 * GNUNET_TIME_absolute_get_duration (
942 pg->feedback_last).rel_value_us);
946 case GNUNET_ATS_PREFERENCE_LATENCY:
947 dur = GNUNET_TIME_absolute_get_duration (pg->feedback_last_delay_update);
948 delay_acc_in = dur.rel_value_us * pg->last_delay_value
949 + pg->feedback_delay_acc;
950 pg->feedback_delay_acc = 0;
952 p_new = get_preference (pg);
953 feedback = (p_new / pg->pref_latency_old) * (delay_acc_in)
954 / (GNUNET_TIME_absolute_get_duration (
955 pg->feedback_last).rel_value_us);
964 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
965 "Giving feedback for peer [%u] for client %p pref %s of %.3f\n",
966 pg->peer, NULL + (pg->client_id),
967 GNUNET_ATS_print_preference_type (pg->kind),
970 sh->sf->s_feedback (sh->sf->cls, NULL + (pg->client_id), &p->peer_id,
971 pg->feedback_frequency, pg->kind, feedback);
972 pg->feedback_last = GNUNET_TIME_absolute_get ();
975 pg->feedback_bw_out_acc = 0;
976 pg->feedback_bw_in_acc = 0;
977 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get ();
979 pg->feedback_delay_acc = 0;
980 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get ();
983 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (pg->feedback_frequency,
984 &set_feedback_task, pg);
989 set_pref_task (void *cls)
991 struct PreferenceGenerator *pg = cls;
997 if (NULL == (p = find_peer_by_id (pg->peer)))
1000 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1001 "Setting preference for unknown peer %u\n", pg->peer);
1005 pref_value = get_preference (pg);
1008 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
1009 pg->pref_bw_old = pref_value;
1012 case GNUNET_ATS_PREFERENCE_LATENCY:
1013 pg->pref_latency_old = pref_value;
1020 p->pref_abs[pg->kind] = pref_value;
1022 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1023 "Setting preference for peer [%u] for client %p pref %s to %f\n",
1024 pg->peer, NULL + (pg->client_id),
1025 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
1027 if (GNUNET_YES == opt_disable_normalization)
1029 p->pref_abs[pg->kind] = pref_value;
1030 p->pref_norm[pg->kind] = pref_value;
1031 sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
1034 update_preference (NULL + (pg->client_id),
1039 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
1045 static struct PreferenceGenerator *
1046 find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
1048 struct PreferenceGenerator *cur;
1050 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
1051 if (cur->peer == peer)
1053 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
1060 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
1062 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
1064 if (NULL != pg->feedback_task)
1066 GNUNET_SCHEDULER_cancel (pg->feedback_task);
1067 pg->feedback_task = NULL;
1070 if (NULL != pg->set_task)
1072 GNUNET_SCHEDULER_cancel (pg->set_task);
1073 pg->set_task = NULL;
1075 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1076 "Removing old up preference generator peer [%u] `%s'\n",
1077 pg->peer, GNUNET_ATS_print_preference_type (pg->kind));
1083 static struct TestAddress*
1084 find_active_address (struct TestPeer *p)
1086 struct TestAddress *cur;
1088 for (cur = p->addr_head; NULL != cur; cur = cur->next)
1089 if (GNUNET_YES == cur->ats_addr->active)
1096 * Generate between the source master and the partner and set property with a
1097 * value depending on the generator.
1099 * @param peer source
1100 * @param address_id partner
1101 * @param client_id the client
1102 * @param type type of generator
1103 * @param base_value base value
1104 * @param value_rate maximum value
1105 * @param period duration of a period of generation (~ 1/frequency)
1106 * @param frequency how long to generate property
1107 * @param kind ATS preference to generate
1108 * @param feedback_frequency how often to give feedback
1109 * @return the preference generator
1111 struct PreferenceGenerator *
1112 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
1113 unsigned int address_id,
1114 unsigned int client_id,
1115 enum GeneratorType type,
1116 long int base_value,
1117 long int value_rate,
1118 struct GNUNET_TIME_Relative
1120 struct GNUNET_TIME_Relative
1122 enum GNUNET_ATS_PreferenceKind
1124 struct GNUNET_TIME_Relative
1127 struct PreferenceGenerator *pg;
1130 if (NULL == (p = find_peer_by_id (peer)))
1133 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1134 "Starting preference for unknown peer %u\n", peer);
1138 pg = GNUNET_new (struct PreferenceGenerator);
1139 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
1142 pg->client_id = client_id;
1144 pg->base_value = base_value;
1145 pg->max_value = value_rate;
1146 pg->duration_period = period;
1147 pg->frequency = frequency;
1148 pg->time_start = GNUNET_TIME_absolute_get ();
1149 pg->feedback_frequency = feedback_frequency;
1153 case GNUNET_ATS_TEST_TG_CONSTANT:
1154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1155 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
1156 print_generator_type (type), pg->peer,
1157 GNUNET_ATS_print_preference_type (kind),
1161 case GNUNET_ATS_TEST_TG_LINEAR:
1162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1163 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
1164 print_generator_type (type), pg->peer,
1165 GNUNET_ATS_print_preference_type (kind),
1166 base_value, value_rate);
1169 case GNUNET_ATS_TEST_TG_SINUS:
1170 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1171 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
1172 print_generator_type (type), pg->peer,
1173 GNUNET_ATS_print_preference_type (kind),
1174 base_value, value_rate);
1177 case GNUNET_ATS_TEST_TG_RANDOM:
1178 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1179 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1180 print_generator_type (type), pg->peer,
1181 GNUNET_ATS_print_preference_type (kind),
1182 base_value, value_rate);
1189 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1190 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us !=
1191 feedback_frequency.rel_value_us)
1193 struct TestAddress *addr = find_active_address (p);
1195 pg->last_assigned_bw_in = p->assigned_bw_in;
1196 pg->last_assigned_bw_out = p->assigned_bw_out;
1197 pg->feedback_bw_in_acc = 0;
1198 pg->feedback_bw_out_acc = 0;
1199 pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
1200 pg->feedback_delay_acc = 0;
1202 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get ();
1203 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get ();
1204 pg->feedback_last = GNUNET_TIME_absolute_get ();
1205 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
1206 &set_feedback_task, pg);
1215 * Stop all preferences generators
1218 GNUNET_ATS_solver_generate_preferences_stop_all ()
1220 struct PreferenceGenerator *cur;
1221 struct PreferenceGenerator *next;
1223 next = pref_gen_head;
1224 for (cur = next; NULL != cur; cur = next)
1227 GNUNET_ATS_solver_generate_preferences_stop (cur);
1237 print_op (enum OperationType op)
1241 case SOLVER_OP_ADD_ADDRESS:
1242 return "ADD_ADDRESS";
1244 case SOLVER_OP_DEL_ADDRESS:
1245 return "DEL_ADDRESS";
1247 case SOLVER_OP_START_SET_PREFERENCE:
1248 return "START_SET_PREFERENCE";
1250 case SOLVER_OP_STOP_SET_PREFERENCE:
1251 return "STOP_STOP_PREFERENCE";
1253 case SOLVER_OP_START_SET_PROPERTY:
1254 return "START_SET_PROPERTY";
1256 case SOLVER_OP_STOP_SET_PROPERTY:
1257 return "STOP_SET_PROPERTY";
1259 case SOLVER_OP_START_REQUEST:
1260 return "START_REQUEST";
1262 case SOLVER_OP_STOP_REQUEST:
1263 return "STOP_REQUEST";
1272 static struct Experiment *
1273 create_experiment ()
1275 struct Experiment *e;
1277 e = GNUNET_new (struct Experiment);
1280 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1286 free_experiment (struct Experiment *e)
1288 struct Episode *cur;
1289 struct Episode *next;
1290 struct GNUNET_ATS_TEST_Operation *cur_o;
1291 struct GNUNET_ATS_TEST_Operation *next_o;
1294 for (cur = next; NULL != cur; cur = next)
1299 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1301 next_o = cur_o->next;
1302 GNUNET_free_non_null (cur_o->address);
1303 GNUNET_free_non_null (cur_o->plugin);
1304 GNUNET_free (cur_o);
1309 GNUNET_free_non_null (e->name);
1310 GNUNET_free_non_null (e->log_prefix);
1311 GNUNET_free_non_null (e->log_output_dir);
1312 GNUNET_free_non_null (e->cfg_file);
1318 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1322 const struct GNUNET_CONFIGURATION_Handle *cfg)
1328 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1329 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1333 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1334 op_counter, "ADD_ADDRESS", op_name);
1335 GNUNET_free (op_name);
1336 return GNUNET_SYSERR;
1338 GNUNET_free (op_name);
1341 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1342 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1347 "Missing address-id in operation %u `%s' in episode `%s'\n",
1348 op_counter, "ADD_ADDRESS", op_name);
1349 GNUNET_free (op_name);
1350 return GNUNET_SYSERR;
1352 GNUNET_free (op_name);
1355 GNUNET_asprintf (&op_name, "op-%u-plugin", op_counter);
1356 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1360 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1361 op_counter, "ADD_ADDRESS", op_name);
1362 GNUNET_free (op_name);
1363 return GNUNET_SYSERR;
1365 GNUNET_free (op_name);
1368 GNUNET_asprintf (&op_name, "op-%u-address", op_counter);
1369 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1373 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1374 op_counter, "ADD_ADDRESS", op_name);
1375 GNUNET_free (op_name);
1376 return GNUNET_SYSERR;
1378 GNUNET_free (op_name);
1381 GNUNET_asprintf (&op_name, "op-%u-address-session", op_counter);
1382 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1388 "Missing address-session in operation %u `%s' in episode `%s'\n",
1389 op_counter, "ADD_ADDRESS", op_name);
1390 GNUNET_free (op_name);
1391 return GNUNET_SYSERR;
1393 GNUNET_free (op_name);
1396 GNUNET_asprintf (&op_name, "op-%u-address-network", op_counter);
1397 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1402 "Missing address-network in operation %u `%s' in episode `%s'\n",
1403 op_counter, "ADD_ADDRESS", op_name);
1404 GNUNET_free (op_name);
1405 return GNUNET_SYSERR;
1409 GNUNET_STRINGS_utf8_toupper (op_network, op_network);
1410 if (0 == strcmp (op_network, "UNSPECIFIED"))
1412 o->address_network = GNUNET_NT_UNSPECIFIED;
1414 else if (0 == strcmp (op_network, "LOOPBACK"))
1416 o->address_network = GNUNET_NT_LOOPBACK;
1418 else if (0 == strcmp (op_network, "LAN"))
1420 o->address_network = GNUNET_NT_LAN;
1422 else if (0 == strcmp (op_network, "WAN"))
1424 o->address_network = GNUNET_NT_WAN;
1426 else if (0 == strcmp (op_network, "WLAN"))
1428 o->address_network = GNUNET_NT_WLAN;
1430 else if (0 == strcmp (op_network, "BT"))
1432 o->address_network = GNUNET_NT_BT;
1437 "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1438 op_counter, "ADD_ADDRESS", op_name, op_network);
1439 GNUNET_free (op_network);
1440 GNUNET_free (op_name);
1441 return GNUNET_SYSERR;
1444 GNUNET_free (op_network);
1445 GNUNET_free (op_name);
1447 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1448 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1449 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1456 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1460 const struct GNUNET_CONFIGURATION_Handle *cfg)
1464 // char *op_network;
1467 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1468 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1472 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1473 op_counter, "DEL_ADDRESS", op_name);
1474 GNUNET_free (op_name);
1475 return GNUNET_SYSERR;
1477 GNUNET_free (op_name);
1480 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1481 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1486 "Missing address-id in operation %u `%s' in episode `%s'\n",
1487 op_counter, "DEL_ADDRESS", op_name);
1488 GNUNET_free (op_name);
1489 return GNUNET_SYSERR;
1491 GNUNET_free (op_name);
1495 GNUNET_asprintf (&op_name, "op-%u-plugin", op_counter);
1496 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1500 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1501 op_counter, "DEL_ADDRESS", op_name);
1502 GNUNET_free (op_name);
1503 return GNUNET_SYSERR;
1505 GNUNET_free (op_name);
1508 GNUNET_asprintf (&op_name, "op-%u-address", op_counter);
1509 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1513 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1514 op_counter, "DEL_ADDRESS", op_name);
1515 GNUNET_free (op_name);
1516 return GNUNET_SYSERR;
1518 GNUNET_free (op_name);
1521 GNUNET_asprintf (&op_name, "op-%u-address-session", op_counter);
1522 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1528 "Missing address-session in operation %u `%s' in episode `%s'\n",
1529 op_counter, "DEL_ADDRESS", op_name);
1530 GNUNET_free (op_name);
1531 return GNUNET_SYSERR;
1533 GNUNET_free (op_name);
1536 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1537 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1538 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1544 static enum GNUNET_ATS_Property
1545 parse_preference_string (const char *str)
1548 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1550 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1551 if (0 == strcmp (str, props[c]))
1558 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1562 const struct GNUNET_CONFIGURATION_Handle *cfg)
1569 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1570 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1574 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1575 op_counter, "START_SET_PREFERENCE", op_name);
1576 GNUNET_free (op_name);
1577 return GNUNET_SYSERR;
1579 GNUNET_free (op_name);
1582 GNUNET_asprintf (&op_name, "op-%u-client-id", op_counter);
1583 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1587 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1588 op_counter, "START_SET_PREFERENCE", op_name);
1589 GNUNET_free (op_name);
1590 return GNUNET_SYSERR;
1592 GNUNET_free (op_name);
1595 GNUNET_asprintf (&op_name, "op-%u-gen-type", op_counter);
1596 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1600 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1601 op_counter, "START_SET_PREFERENCE", op_name);
1602 GNUNET_free (op_name);
1603 return GNUNET_SYSERR;
1606 /* Load arguments for set_rate, start_send, set_preference */
1607 if (0 == strcmp (type, "constant"))
1609 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1611 else if (0 == strcmp (type, "linear"))
1613 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1615 else if (0 == strcmp (type, "sinus"))
1617 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1619 else if (0 == strcmp (type, "random"))
1621 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1625 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1626 op_counter, op_name, e->id);
1628 GNUNET_free (op_name);
1629 return GNUNET_SYSERR;
1632 GNUNET_free (op_name);
1636 GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter);
1637 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1641 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1642 op_counter, op_name, e->id);
1643 GNUNET_free (op_name);
1644 return GNUNET_SYSERR;
1646 GNUNET_free (op_name);
1650 GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter);
1651 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1655 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1656 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1657 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1659 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1660 op_counter, op_name, e->id);
1661 GNUNET_free (op_name);
1662 return GNUNET_SYSERR;
1665 GNUNET_free (op_name);
1668 GNUNET_asprintf (&op_name, "op-%u-period", op_counter);
1669 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1673 o->period = e->duration;
1675 GNUNET_free (op_name);
1678 GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter);
1679 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1683 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1684 op_counter, op_name, e->id);
1685 GNUNET_free (op_name);
1686 return GNUNET_SYSERR;
1688 GNUNET_free (op_name);
1690 /* Get preference */
1691 GNUNET_asprintf (&op_name, "op-%u-pref", op_counter);
1692 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1696 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1697 op_counter, op_name, e->id);
1698 GNUNET_free (op_name);
1699 return GNUNET_SYSERR;
1702 if (0 == (o->pref_type = parse_preference_string (pref)))
1704 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1705 op_counter, op_name, e->id);
1706 GNUNET_free (op_name);
1708 return GNUNET_SYSERR;
1711 GNUNET_free (op_name);
1713 /* Get feedback delay */
1714 GNUNET_asprintf (&op_name, "op-%u-feedback_delay", op_counter);
1715 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
1717 &o->feedback_delay))
1720 "Using feedback delay %llu in operation %u `%s' in episode %u\n",
1721 (long long unsigned int) o->feedback_delay.rel_value_us,
1722 op_counter, op_name, e->id);
1725 o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
1726 GNUNET_free (op_name);
1728 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1729 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1730 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1731 GNUNET_ATS_print_preference_type (o->pref_type), o->base_rate);
1738 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1742 const struct GNUNET_CONFIGURATION_Handle *cfg)
1748 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1749 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1753 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1754 op_counter, "STOP_SET_PREFERENCE", op_name);
1755 GNUNET_free (op_name);
1756 return GNUNET_SYSERR;
1758 GNUNET_free (op_name);
1761 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1762 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1767 "Missing address-id in operation %u `%s' in episode `%s'\n",
1768 op_counter, "STOP_SET_PREFERENCE", op_name);
1769 GNUNET_free (op_name);
1770 return GNUNET_SYSERR;
1772 GNUNET_free (op_name);
1774 /* Get preference */
1775 GNUNET_asprintf (&op_name, "op-%u-pref", op_counter);
1776 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1781 "Missing preference in operation %u `%s' in episode `%s'\n",
1782 op_counter, "STOP_SET_PREFERENCE", op_name);
1783 GNUNET_free (op_name);
1784 return GNUNET_SYSERR;
1787 if (0 == (o->pref_type = parse_preference_string (pref)))
1789 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1790 op_counter, op_name, e->id);
1791 GNUNET_free (op_name);
1793 return GNUNET_SYSERR;
1796 GNUNET_free (op_name);
1798 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1799 "Found operation %s: [%llu:%llu]: %s\n",
1800 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1801 GNUNET_ATS_print_preference_type (o->pref_type));
1806 static enum GNUNET_ATS_Property
1807 parse_property_string (const char *str)
1809 enum GNUNET_ATS_Property c;
1811 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1812 if (0 == strcmp (str,
1813 GNUNET_ATS_print_property_type (c)))
1820 load_op_start_set_property (struct GNUNET_ATS_TEST_Operation *o,
1824 const struct GNUNET_CONFIGURATION_Handle *cfg)
1831 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1832 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1836 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1837 op_counter, "START_SET_PROPERTY", op_name);
1838 GNUNET_free (op_name);
1839 return GNUNET_SYSERR;
1841 GNUNET_free (op_name);
1844 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1845 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1850 "Missing address-id in operation %u `%s' in episode `%s'\n",
1851 op_counter, "START_SET_PROPERTY", op_name);
1852 GNUNET_free (op_name);
1853 return GNUNET_SYSERR;
1855 GNUNET_free (op_name);
1858 GNUNET_asprintf (&op_name, "op-%u-gen-type", op_counter);
1859 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1863 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1864 op_counter, "START_SET_PROPERTY", op_name);
1865 GNUNET_free (op_name);
1866 return GNUNET_SYSERR;
1869 /* Load arguments for set_rate, start_send, set_preference */
1870 if (0 == strcmp (type, "constant"))
1872 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1874 else if (0 == strcmp (type, "linear"))
1876 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1878 else if (0 == strcmp (type, "sinus"))
1880 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1882 else if (0 == strcmp (type, "random"))
1884 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1888 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1889 op_counter, op_name, e->id);
1891 GNUNET_free (op_name);
1892 return GNUNET_SYSERR;
1895 GNUNET_free (op_name);
1899 GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter);
1900 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1904 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1905 op_counter, op_name, e->id);
1906 GNUNET_free (op_name);
1907 return GNUNET_SYSERR;
1909 GNUNET_free (op_name);
1913 GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter);
1914 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1918 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1919 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1920 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1922 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1923 op_counter, op_name, e->id);
1924 GNUNET_free (op_name);
1925 return GNUNET_SYSERR;
1928 GNUNET_free (op_name);
1931 GNUNET_asprintf (&op_name, "op-%u-period", op_counter);
1932 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1936 o->period = e->duration;
1938 GNUNET_free (op_name);
1941 GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter);
1942 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1946 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1947 op_counter, op_name, e->id);
1948 GNUNET_free (op_name);
1949 return GNUNET_SYSERR;
1951 GNUNET_free (op_name);
1953 /* Get preference */
1954 GNUNET_asprintf (&op_name, "op-%u-property", op_counter);
1955 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1959 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1960 op_counter, op_name, e->id);
1961 GNUNET_free (op_name);
1962 GNUNET_free_non_null (prop);
1963 return GNUNET_SYSERR;
1966 if (0 == (o->prop_type = parse_property_string (prop)))
1968 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1969 op_counter, op_name, e->id);
1970 GNUNET_free (op_name);
1972 return GNUNET_SYSERR;
1976 GNUNET_free (op_name);
1978 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1979 "Found operation %s: [%llu:%llu] %s = %llu\n",
1980 "START_SET_PROPERTY", o->peer_id, o->address_id,
1981 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1987 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1991 const struct GNUNET_CONFIGURATION_Handle *cfg)
1997 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1998 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2002 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
2003 op_counter, "STOP_SET_PROPERTY", op_name);
2004 GNUNET_free (op_name);
2005 return GNUNET_SYSERR;
2007 GNUNET_free (op_name);
2010 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
2011 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2016 "Missing address-id in operation %u `%s' in episode `%s'\n",
2017 op_counter, "STOP_SET_PROPERTY", op_name);
2018 GNUNET_free (op_name);
2019 return GNUNET_SYSERR;
2021 GNUNET_free (op_name);
2024 GNUNET_asprintf (&op_name, "op-%u-property", op_counter);
2025 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2029 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
2030 op_counter, "STOP_SET_PROPERTY", op_name);
2031 GNUNET_free (op_name);
2032 GNUNET_free_non_null (pref);
2033 return GNUNET_SYSERR;
2036 if (0 == (o->prop_type = parse_property_string (pref)))
2038 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
2039 op_counter, op_name, e->id);
2040 GNUNET_free (op_name);
2041 GNUNET_free_non_null (pref);
2042 return GNUNET_SYSERR;
2046 GNUNET_free (op_name);
2048 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2049 "Found operation %s: [%llu:%llu] %s\n",
2050 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
2051 GNUNET_ATS_print_property_type (o->prop_type));
2058 load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
2062 const struct GNUNET_CONFIGURATION_Handle *cfg)
2067 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
2068 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2072 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
2073 op_counter, "START_REQUEST", op_name);
2074 GNUNET_free (op_name);
2075 return GNUNET_SYSERR;
2077 GNUNET_free (op_name);
2082 load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
2086 const struct GNUNET_CONFIGURATION_Handle *cfg)
2091 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
2092 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2096 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
2097 op_counter, "STOP_REQUEST", op_name);
2098 GNUNET_free (op_name);
2099 return GNUNET_SYSERR;
2101 GNUNET_free (op_name);
2107 load_episode (struct Experiment *e, struct Episode *cur,
2108 struct GNUNET_CONFIGURATION_Handle *cfg)
2110 struct GNUNET_ATS_TEST_Operation *o;
2117 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n", cur->id);
2118 GNUNET_asprintf (&sec_name, "episode-%u", cur->id);
2122 /* Load operation */
2123 GNUNET_asprintf (&op_name, "op-%u-operation", op_counter);
2124 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2128 GNUNET_free (op_name);
2131 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
2132 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
2135 /* operations = set_rate, start_send, stop_send, set_preference */
2136 if (0 == strcmp (op, "address_add"))
2138 o->type = SOLVER_OP_ADD_ADDRESS;
2139 res = load_op_add_address (o, cur,
2140 op_counter, sec_name, cfg);
2142 else if (0 == strcmp (op, "address_del"))
2144 o->type = SOLVER_OP_DEL_ADDRESS;
2145 res = load_op_del_address (o, cur,
2146 op_counter, sec_name, cfg);
2148 else if (0 == strcmp (op, "start_set_property"))
2150 o->type = SOLVER_OP_START_SET_PROPERTY;
2151 res = load_op_start_set_property (o, cur,
2152 op_counter, sec_name, cfg);
2154 else if (0 == strcmp (op, "stop_set_property"))
2156 o->type = SOLVER_OP_STOP_SET_PROPERTY;
2157 res = load_op_stop_set_property (o, cur,
2158 op_counter, sec_name, cfg);
2160 else if (0 == strcmp (op, "start_set_preference"))
2162 o->type = SOLVER_OP_START_SET_PREFERENCE;
2163 res = load_op_start_set_preference (o, cur,
2164 op_counter, sec_name, cfg);
2166 else if (0 == strcmp (op, "stop_set_preference"))
2168 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
2169 res = load_op_stop_set_preference (o, cur,
2170 op_counter, sec_name, cfg);
2172 else if (0 == strcmp (op, "start_request"))
2174 o->type = SOLVER_OP_START_REQUEST;
2175 res = load_op_start_request (o, cur,
2176 op_counter, sec_name, cfg);
2178 else if (0 == strcmp (op, "stop_request"))
2180 o->type = SOLVER_OP_STOP_REQUEST;
2181 res = load_op_stop_request (o, cur,
2182 op_counter, sec_name, cfg);
2186 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
2187 op_counter, op, cur->id);
2188 res = GNUNET_SYSERR;
2192 GNUNET_free (op_name);
2194 if (GNUNET_SYSERR == res)
2197 GNUNET_free (sec_name);
2198 return GNUNET_SYSERR;
2201 GNUNET_CONTAINER_DLL_insert_tail (cur->head, cur->tail, o);
2204 GNUNET_free (sec_name);
2209 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
2213 struct GNUNET_TIME_Relative e_duration;
2214 struct Episode *cur;
2215 struct Episode *last;
2221 GNUNET_asprintf (&sec_name, "episode-%u", e_counter);
2222 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
2227 GNUNET_free (sec_name);
2231 cur = GNUNET_new (struct Episode);
2232 cur->duration = e_duration;
2233 cur->id = e_counter;
2235 if (GNUNET_OK != load_episode (e, cur, cfg))
2237 GNUNET_free (sec_name);
2239 return GNUNET_SYSERR;
2242 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2244 GNUNET_STRINGS_relative_time_to_string (cur->duration,
2247 /* Update experiment */
2249 e->total_duration = GNUNET_TIME_relative_add (e->total_duration,
2251 /* Put in linked list */
2257 GNUNET_free (sec_name);
2266 timeout_experiment (void *cls)
2268 struct Experiment *e = cls;
2270 e->experiment_timeout_task = NULL;
2271 fprintf (stderr, "Experiment timeout!\n");
2273 if (NULL != e->episode_timeout_task)
2275 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2276 e->episode_timeout_task = NULL;
2279 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
2283 struct ATS_Address *
2284 create_ats_address (const struct GNUNET_PeerIdentity *peer,
2285 const char *plugin_name,
2286 const void *plugin_addr,
2287 size_t plugin_addr_len,
2288 uint32_t session_id,
2291 struct ATS_Address *aa = NULL;
2293 aa = GNUNET_malloc (sizeof(struct ATS_Address) + plugin_addr_len + strlen (
2295 aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
2296 aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
2297 aa->atsi[0].value = htonl (network);
2301 aa->addr_len = plugin_addr_len;
2303 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2304 GNUNET_memcpy (&aa[1], plugin_addr, plugin_addr_len);
2305 GNUNET_memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2306 aa->session_id = session_id;
2314 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2317 struct TestAddress *a;
2320 if (NULL == (p = find_peer_by_id (op->peer_id)))
2322 p = GNUNET_new (struct TestPeer);
2323 p->id = op->peer_id;
2324 p->assigned_bw_in = 0;
2325 p->assigned_bw_out = 0;
2326 memset (&p->peer_id, op->peer_id, sizeof(p->peer_id));
2327 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2329 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2330 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2333 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2336 if (NULL != (find_address_by_id (p, op->address_id)))
2338 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2339 op->address_id, op->peer_id);
2343 a = GNUNET_new (struct TestAddress);
2344 a->aid = op->address_id;
2345 a->network = op->address_network;
2346 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2347 strlen (op->address) + 1,
2348 op->address_session, op->address_network);
2349 memset (&p->peer_id, op->peer_id, sizeof(p->peer_id));
2350 GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
2352 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2353 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2355 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2356 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2358 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2359 "Adding address %u for peer %u in network `%s'\n",
2360 op->address_id, op->peer_id, GNUNET_NT_to_string (a->network));
2362 sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
2367 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2370 struct TestAddress *a;
2371 struct PropertyGenerator *pg;
2373 if (NULL == (p = find_peer_by_id (op->peer_id)))
2376 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2377 "Deleting address for unknown peer %u\n", op->peer_id);
2381 if (NULL == (a = find_address_by_id (p, op->address_id)))
2384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2385 "Deleting address for unknown peer %u\n", op->peer_id);
2389 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2391 GNUNET_ATS_solver_generate_property_stop (pg);
2394 GNUNET_assert (GNUNET_YES ==
2395 GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
2398 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2399 "Removing address %u for peer %u\n",
2403 sh->sf->s_del (sh->sf->cls, a->ats_addr);
2407 GNUNET_ATS_solver_logging_now (l);
2409 GNUNET_CONTAINER_DLL_remove (p->addr_head, p->addr_tail, a);
2411 GNUNET_free_non_null (a->ats_addr->atsi);
2412 GNUNET_free (a->ats_addr);
2417 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2419 struct PropertyGenerator *pg;
2421 struct TestAddress *a;
2423 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2425 GNUNET_ATS_solver_generate_property_stop (pg);
2429 if (NULL == (p = find_peer_by_id (op->peer_id)))
2432 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2433 "Starting property generation for unknown peer %u\n",
2438 if (NULL == (a = find_address_by_id (p, op->address_id)))
2441 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2442 "Setting property for unknown address %u\n", op->peer_id);
2446 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2458 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2460 struct PropertyGenerator *pg = find_prop_gen (op->peer_id, op->address_id,
2465 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2466 "Stopping preference generation for peer %u address %u\n",
2469 GNUNET_ATS_solver_generate_property_stop (pg);
2473 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2474 "Cannot find preference generator for peer %u address %u\n",
2475 op->peer_id, op->address_id);
2481 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2483 struct PreferenceGenerator *pg;
2485 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2487 GNUNET_ATS_solver_generate_preferences_stop (pg);
2491 if (NULL == (find_peer_by_id (op->peer_id)))
2494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2495 "Starting preference generation for unknown peer %u\n",
2500 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2513 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2515 struct PreferenceGenerator *pg = find_pref_gen (op->peer_id,
2520 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2521 "Stopping property generation for peer %u address %u\n",
2524 GNUNET_ATS_solver_generate_preferences_stop (pg);
2528 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2529 "Cannot find preference generator for peer %u address %u\n",
2530 op->peer_id, op->address_id);
2537 enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2541 if (NULL == (p = find_peer_by_id (op->peer_id)))
2544 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2545 "Requesting address for unknown peer %u\n", op->peer_id);
2549 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2551 p->is_requested = GNUNET_YES;
2553 sh->sf->s_get (sh->sf->cls, &p->peer_id);
2558 enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
2562 if (NULL == (p = find_peer_by_id (op->peer_id)))
2565 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2566 "Requesting address for unknown peer %u\n", op->peer_id);
2570 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2571 "Stop requesting address for peer %u\n",
2573 p->is_requested = GNUNET_NO;
2574 p->assigned_bw_in = 0;
2575 p->assigned_bw_out = 0;
2576 sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
2580 GNUNET_ATS_solver_logging_now (l);
2584 static void enforce_episode (struct Episode *ep)
2586 struct GNUNET_ATS_TEST_Operation *cur;
2588 for (cur = ep->head; NULL != cur; cur = cur->next)
2592 case SOLVER_OP_ADD_ADDRESS:
2593 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2594 print_op (cur->type), cur->peer_id, cur->address_id);
2595 enforce_add_address (cur);
2598 case SOLVER_OP_DEL_ADDRESS:
2599 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2600 print_op (cur->type), cur->peer_id, cur->address_id);
2601 enforce_del_address (cur);
2604 case SOLVER_OP_START_SET_PROPERTY:
2605 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2606 print_op (cur->type), cur->peer_id, cur->address_id,
2608 enforce_start_property (cur);
2611 case SOLVER_OP_STOP_SET_PROPERTY:
2612 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2613 print_op (cur->type), cur->peer_id, cur->address_id,
2615 enforce_stop_property (cur);
2618 case SOLVER_OP_START_SET_PREFERENCE:
2619 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2620 print_op (cur->type), cur->peer_id, cur->address_id,
2622 enforce_start_preference (cur);
2625 case SOLVER_OP_STOP_SET_PREFERENCE:
2626 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2627 print_op (cur->type), cur->peer_id, cur->address_id,
2629 enforce_stop_preference (cur);
2632 case SOLVER_OP_START_REQUEST:
2633 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2634 print_op (cur->type), cur->peer_id);
2635 enforce_start_request (cur);
2638 case SOLVER_OP_STOP_REQUEST:
2639 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2640 print_op (cur->type), cur->peer_id);
2641 enforce_stop_request (cur);
2652 timeout_episode (void *cls)
2654 struct Experiment *e = cls;
2656 e->episode_timeout_task = NULL;
2657 if (NULL != e->ep_done_cb)
2658 e->ep_done_cb (e->cur);
2660 /* Scheduling next */
2661 e->cur = e->cur->next;
2665 fprintf (stderr, "Last episode done!\n");
2666 if (NULL != e->experiment_timeout_task)
2668 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2669 e->experiment_timeout_task = NULL;
2671 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
2676 fprintf (stderr, "Running episode %u with timeout %s\n",
2678 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
2680 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2681 &timeout_episode, e);
2682 enforce_episode (e->cur);
2687 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2688 GNUNET_ATS_TESTING_EpisodeDoneCallback
2690 GNUNET_ATS_TESTING_ExperimentDoneCallback
2693 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2694 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
2696 e->e_done_cb = e_done_cb;
2697 e->ep_done_cb = ep_done_cb;
2698 e->start_time = GNUNET_TIME_absolute_get ();
2700 /* Start total time out */
2701 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2702 &timeout_experiment,
2706 if (NULL == e->start)
2713 fprintf (stderr, "Running episode %u with timeout %s\n",
2715 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
2717 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2718 &timeout_episode, e);
2719 enforce_episode (e->cur);
2723 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2725 if (NULL != e->experiment_timeout_task)
2727 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2728 e->experiment_timeout_task = NULL;
2730 if (NULL != e->episode_timeout_task)
2732 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2733 e->episode_timeout_task = NULL;
2737 GNUNET_CONFIGURATION_destroy (e->cfg);
2740 free_experiment (e);
2745 GNUNET_ATS_solvers_experimentation_load (char *filename)
2747 struct Experiment *e;
2748 struct GNUNET_CONFIGURATION_Handle *cfg;
2752 cfg = GNUNET_CONFIGURATION_create ();
2753 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2755 fprintf (stderr, "Failed to load `%s'\n", filename);
2756 GNUNET_CONFIGURATION_destroy (cfg);
2760 e = create_experiment ();
2762 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment",
2765 fprintf (stderr, "Invalid %s \n", "name");
2766 free_experiment (e);
2770 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2772 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment",
2776 fprintf (stderr, "Invalid %s \n", "log_prefix");
2777 free_experiment (e);
2781 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2784 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg,
2790 e->log_output_dir = NULL;
2793 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2794 "Experiment logging output directory: `%s'\n",
2798 if (GNUNET_SYSERR == (e->log_append_time_stamp =
2799 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2801 "log_append_time_stamp")))
2802 e->log_append_time_stamp = GNUNET_YES;
2803 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2804 "Experiment logging append timestamp: `%s'\n",
2805 (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
2808 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg,
2813 fprintf (stderr, "Invalid %s \n", "cfg_file");
2814 free_experiment (e);
2819 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n",
2821 e->cfg = GNUNET_CONFIGURATION_create ();
2822 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2824 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2825 free_experiment (e);
2830 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
2834 fprintf (stderr, "Invalid %s \n", "log_freq");
2835 free_experiment (e);
2839 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2840 GNUNET_STRINGS_relative_time_to_string (e->log_freq,
2843 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
2847 fprintf (stderr, "Invalid %s", "max_duration");
2848 free_experiment (e);
2852 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2853 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
2856 if (GNUNET_SYSERR == load_episodes (e, cfg))
2858 GNUNET_ATS_solvers_experimentation_stop (e);
2859 GNUNET_CONFIGURATION_destroy (cfg);
2861 fprintf (stderr, "Failed to load experiment\n");
2864 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2865 "Loaded %u episodes with total duration %s\n",
2867 GNUNET_STRINGS_relative_time_to_string (e->total_duration,
2870 GNUNET_CONFIGURATION_destroy (cfg);
2881 free_all_it (void *cls,
2882 const struct GNUNET_PeerIdentity *key,
2885 struct ATS_Address *address = value;
2887 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (
2890 GNUNET_free (address);
2896 GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2898 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2900 GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
2902 GAS_normalization_stop ();
2904 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
2907 GNUNET_CONTAINER_multipeermap_destroy (sh->addresses);
2908 GNUNET_free (sh->plugin);
2914 * Load quotas for networks from configuration
2916 * @param cfg configuration handle
2917 * @param out_dest where to write outbound quotas
2918 * @param in_dest where to write inbound quotas
2919 * @param dest_length length of inbound and outbound arrays
2920 * @return number of networks loaded
2923 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2924 unsigned long long *out_dest,
2925 unsigned long long *in_dest,
2928 char *entry_in = NULL;
2929 char *entry_out = NULL;
2930 char *quota_out_str;
2935 for (c = 0; (c < GNUNET_NT_COUNT) && (c < dest_length); c++)
2939 GNUNET_asprintf (&entry_out,
2941 GNUNET_NT_to_string (c));
2942 GNUNET_asprintf (&entry_in,
2944 GNUNET_NT_to_string (c));
2947 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "ats",
2952 if (0 == strcmp (quota_out_str, BIG_M_STRING))
2954 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2957 if ((GNUNET_NO == res) && (GNUNET_OK ==
2958 GNUNET_STRINGS_fancy_size_to_bytes (
2959 quota_out_str, &out_dest[c])))
2961 if ((GNUNET_NO == res) && (GNUNET_OK ==
2962 GNUNET_CONFIGURATION_get_value_number (cfg,
2970 if (GNUNET_NO == res)
2972 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2974 "Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2975 GNUNET_NT_to_string (c),
2977 GNUNET_ATS_DefaultBandwidth);
2978 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2982 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2983 "Outbound quota configure for network `%s' is %llu\n",
2984 GNUNET_NT_to_string (c),
2987 GNUNET_free (quota_out_str);
2991 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2993 "No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
2994 GNUNET_NT_to_string (c),
2995 GNUNET_ATS_DefaultBandwidth);
2996 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
3000 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "ats",
3005 if (0 == strcmp (quota_in_str, BIG_M_STRING))
3007 in_dest[c] = GNUNET_ATS_MaxBandwidth;
3010 if ((GNUNET_NO == res) && (GNUNET_OK ==
3011 GNUNET_STRINGS_fancy_size_to_bytes (
3012 quota_in_str, &in_dest[c])))
3014 if ((GNUNET_NO == res) && (GNUNET_OK ==
3015 GNUNET_CONFIGURATION_get_value_number (cfg,
3022 if (GNUNET_NO == res)
3024 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3026 "Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
3027 GNUNET_NT_to_string (c),
3029 GNUNET_ATS_DefaultBandwidth);
3030 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
3034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3035 "Inbound quota configured for network `%s' is %llu\n",
3036 GNUNET_NT_to_string (c),
3039 GNUNET_free (quota_in_str);
3043 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3045 "No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
3046 GNUNET_NT_to_string (c),
3047 GNUNET_ATS_DefaultBandwidth);
3048 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
3050 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3051 "Loaded quota for network `%s' (in/out): %llu %llu\n",
3052 GNUNET_NT_to_string (c),
3055 GNUNET_free (entry_out);
3056 GNUNET_free (entry_in);
3058 return GNUNET_NT_COUNT;
3063 * Information callback for the solver
3065 * @param cls the closure
3066 * @param op the solver operation
3067 * @param stat status of the solver operation
3068 * @param add additional solver information
3071 solver_info_cb (void *cls,
3072 enum GAS_Solver_Operation op,
3073 enum GAS_Solver_Status stat,
3074 enum GAS_Solver_Additional_Information add)
3081 add_info = "GAS_INFO_NONE";
3085 add_info = "GAS_INFO_MLP_FULL";
3088 case GAS_INFO_UPDATED:
3089 add_info = "GAS_INFO_MLP_UPDATED";
3092 case GAS_INFO_PROP_ALL:
3093 add_info = "GAS_INFO_PROP_ALL";
3096 case GAS_INFO_PROP_SINGLE:
3097 add_info = "GAS_INFO_PROP_SINGLE";
3101 add_info = "INVALID";
3107 case GAS_OP_SOLVE_START:
3108 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3109 "Solver notifies `%s' with result `%s' `%s'\n",
3110 "GAS_OP_SOLVE_START",
3111 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
3114 case GAS_OP_SOLVE_STOP:
3115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3116 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
3117 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
3120 case GAS_OP_SOLVE_SETUP_START:
3121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3122 "Solver notifies `%s' with result `%s'\n",
3123 "GAS_OP_SOLVE_SETUP_START",
3124 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3127 case GAS_OP_SOLVE_SETUP_STOP:
3128 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3129 "Solver notifies `%s' with result `%s'\n",
3130 "GAS_OP_SOLVE_SETUP_STOP",
3131 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3134 case GAS_OP_SOLVE_MLP_LP_START:
3135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3136 "Solver notifies `%s' with result `%s'\n",
3137 "GAS_OP_SOLVE_LP_START",
3138 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3141 case GAS_OP_SOLVE_MLP_LP_STOP:
3142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3143 "Solver notifies `%s' with result `%s'\n",
3144 "GAS_OP_SOLVE_LP_STOP",
3145 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3148 case GAS_OP_SOLVE_MLP_MLP_START:
3149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3150 "Solver notifies `%s' with result `%s'\n",
3151 "GAS_OP_SOLVE_MLP_START",
3152 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3155 case GAS_OP_SOLVE_MLP_MLP_STOP:
3156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3157 "Solver notifies `%s' with result `%s'\n",
3158 "GAS_OP_SOLVE_MLP_STOP",
3159 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3162 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
3163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3164 "Solver notifies `%s' with result `%s'\n",
3165 "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
3166 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3169 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
3170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3171 "Solver notifies `%s' with result `%s'\n",
3172 "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
3173 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3182 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
3184 struct GNUNET_TIME_Relative duration;
3186 static struct PreferenceGenerator *pg;
3189 if ((0 == address->assigned_bw_out) && (0 == address->assigned_bw_in))
3191 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3192 "Solver notified to disconnect peer `%s'\n",
3193 GNUNET_i2s (&address->peer));
3195 p = find_peer_by_pid (&address->peer);
3198 p->assigned_bw_out = address->assigned_bw_out;
3199 p->assigned_bw_in = address->assigned_bw_in;
3201 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
3203 if (pg->peer == p->id)
3205 duration = GNUNET_TIME_absolute_get_duration (
3206 pg->feedback_last_bw_update);
3207 delta = duration.rel_value_us * pg->last_assigned_bw_out;
3208 pg->feedback_bw_out_acc += delta;
3210 delta = duration.rel_value_us * pg->last_assigned_bw_in;
3211 pg->feedback_bw_in_acc += delta;
3213 pg->last_assigned_bw_in = address->assigned_bw_in;
3214 pg->last_assigned_bw_out = address->assigned_bw_out;
3215 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get ();
3219 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3220 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
3221 GNUNET_i2s (&address->peer),
3223 address->assigned_bw_out,
3224 address->assigned_bw_in);
3227 GNUNET_ATS_solver_logging_now (l);
3233 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3237 if (GNUNET_YES == opt_disable_normalization)
3239 if (NULL == (p = find_peer_by_pid (id)))
3244 return GAS_preference_get_by_peer (NULL,
3249 struct SolverHandle *
3250 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3252 struct SolverHandle *sh;
3257 case GNUNET_ATS_SOLVER_PROPORTIONAL:
3258 solver_str = "proportional";
3261 case GNUNET_ATS_SOLVER_MLP:
3265 case GNUNET_ATS_SOLVER_RIL:
3275 sh = GNUNET_new (struct SolverHandle);
3276 GNUNET_asprintf (&sh->plugin,
3277 "libgnunet_plugin_ats_%s",
3279 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
3281 /* setup environment */
3282 sh->env.cfg = e->cfg;
3283 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
3284 sh->env.addresses = sh->addresses;
3285 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
3286 sh->env.get_preferences = &get_preferences_cb;
3287 sh->env.network_count = GNUNET_NT_COUNT;
3288 sh->env.info_cb = &solver_info_cb;
3289 sh->env.network_count = GNUNET_NT_COUNT;
3291 /* start normalization */
3292 GAS_normalization_start ();
3295 if (GNUNET_NT_COUNT != GNUNET_ATS_solvers_load_quotas (e->cfg,
3301 GNUNET_free (sh->plugin);
3307 sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
3310 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
3312 GNUNET_free (sh->plugin);
3324 struct TestPeer *cur;
3325 struct TestPeer *next;
3327 struct TestAddress *cur_a;
3328 struct TestAddress *next_a;
3331 GNUNET_ATS_solver_logging_stop (l);
3333 /* Stop all preference generation */
3334 GNUNET_ATS_solver_generate_preferences_stop_all ();
3336 /* Stop all property generation */
3337 GNUNET_ATS_solver_generate_property_stop_all ();
3341 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
3342 GNUNET_ATS_solver_logging_eval (l);
3346 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
3347 GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
3353 GNUNET_ATS_solver_logging_free (l);
3357 /* Clean up experiment */
3360 GNUNET_ATS_solvers_experimentation_stop (e);
3365 while (NULL != (cur = next))
3368 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3369 next_a = cur->addr_head;
3370 while (NULL != (cur_a = next_a))
3372 next_a = cur_a->next;
3373 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3374 GNUNET_free (cur_a);
3380 GNUNET_ATS_solvers_solver_stop (sh);
3389 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,
3392 if (GNUNET_OK == success)
3393 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3394 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3396 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3398 GNUNET_SCHEDULER_add_now (&done, NULL);
3402 episode_done_cb (struct Episode *ep)
3404 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3417 GNUNET_ATS_solvers_experimentation_stop (e);
3422 GNUNET_ATS_solvers_solver_stop (sh);
3428 run (void *cls, char *const *args, const char *cfgfile,
3429 const struct GNUNET_CONFIGURATION_Handle *cfg)
3431 enum GNUNET_ATS_Solvers solver;
3434 if (NULL == opt_exp_file)
3436 fprintf (stderr, "No experiment given ...\n");
3442 if (NULL == opt_solver)
3444 fprintf (stderr, "No solver given ...\n");
3450 if (0 == strcmp (opt_solver, "mlp"))
3452 solver = GNUNET_ATS_SOLVER_MLP;
3454 else if (0 == strcmp (opt_solver, "proportional"))
3456 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3458 else if (0 == strcmp (opt_solver, "ril"))
3460 solver = GNUNET_ATS_SOLVER_RIL;
3464 fprintf (stderr, "No solver given ...");
3470 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3471 default_properties[c] = DEFAULT_REL_QUALITY;
3473 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3474 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3476 /* load experiment */
3477 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3478 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3481 fprintf (stderr, "Failed to load experiment ...\n");
3488 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3489 sh = GNUNET_ATS_solvers_solver_start (solver);
3492 fprintf (stderr, "Failed to start solver ...\n");
3499 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3500 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3502 /* run experiment */
3503 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3504 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3505 experiment_done_cb);
3512 * Main function of the benchmark
3514 * @param argc argument count
3515 * @param argv argument values
3518 main (int argc, char *argv[])
3520 opt_exp_file = NULL;
3522 opt_log = GNUNET_NO;
3523 opt_save = GNUNET_NO;
3527 static struct GNUNET_GETOPT_CommandLineOption options[] = {
3528 GNUNET_GETOPT_option_string ('s',
3530 gettext_noop ("solver to use"),
3533 GNUNET_GETOPT_option_string ('e',
3535 gettext_noop ("experiment to use"),
3538 GNUNET_GETOPT_option_verbose (&opt_verbose),
3540 GNUNET_GETOPT_option_flag ('p',
3542 gettext_noop ("print logging"),
3545 GNUNET_GETOPT_option_flag ('f',
3547 gettext_noop ("save logging to disk"),
3550 GNUNET_GETOPT_option_flag ('d',
3552 gettext_noop ("disable normalization"),
3553 &opt_disable_normalization),
3555 GNUNET_GETOPT_OPTION_END
3558 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3559 NULL, options, &run, argv[0]);
3563 /* end of file ats-testing-experiment.c*/