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
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
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)
95 case GNUNET_ATS_TEST_TG_CONSTANT:
97 case GNUNET_ATS_TEST_TG_LINEAR:
99 case GNUNET_ATS_TEST_TG_RANDOM:
101 case GNUNET_ATS_TEST_TG_SINUS:
110 static struct TestPeer *
111 find_peer_by_id (int id)
113 struct TestPeer *cur;
114 for (cur = peer_head; NULL != cur; cur = cur->next)
120 static struct TestPeer *
121 find_peer_by_pid (const struct GNUNET_PeerIdentity *pid)
123 struct TestPeer *cur;
124 for (cur = peer_head; NULL != cur; cur = cur->next)
125 if (0 == memcmp (&cur->peer_id, pid, sizeof (struct GNUNET_PeerIdentity)))
130 static struct TestAddress *
131 find_address_by_id (struct TestPeer *peer, int aid)
133 struct TestAddress *cur;
134 for (cur = peer->addr_head; NULL != cur; cur = cur->next)
145 GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
147 struct LoggingTimeStep *lts;
148 struct TestPeer *cur;
149 struct TestAddress *cur_addr;
150 struct LoggingPeer *log_p;
151 struct LoggingAddress *log_a;
154 lts = GNUNET_new (struct LoggingTimeStep);
155 GNUNET_CONTAINER_DLL_insert_tail(l->head, l->tail, lts);
156 lts->timestamp = GNUNET_TIME_absolute_get();
157 if (NULL == lts->prev)
158 lts->delta = GNUNET_TIME_UNIT_ZERO;
160 lts->delta = GNUNET_TIME_absolute_get_duration(lts->prev->timestamp);
162 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging %llu, delta %llu\n",
163 lts->timestamp.abs_value_us, lts->delta.rel_value_us);
166 /* Store logging data here */
167 for (cur = peer_head; NULL != cur; cur = cur->next)
169 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
170 "Logging peer id %llu\n", cur->id);
172 log_p = GNUNET_new (struct LoggingPeer);
174 log_p->peer_id = cur->peer_id;
175 log_p->is_requested = cur->is_requested;
176 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
178 log_p->pref_abs[c] = cur->pref_abs[c];
179 log_p->pref_norm[c] = cur->pref_norm[c];
180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
181 "\t %s = %.2f %.2f [abs/rel]\n",
182 GNUNET_ATS_print_preference_type(c),
183 log_p->pref_abs[c], log_p->pref_norm[c]);
185 GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p);
187 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
189 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
190 "Logging peer id %llu address %llu\n",
191 cur->id, cur_addr->aid);
192 log_a = GNUNET_new (struct LoggingAddress);
193 log_a->aid = cur_addr->aid;
194 log_a->active = cur_addr->ats_addr->active;
195 log_a->network = cur_addr->network;
196 log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
197 log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
198 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
200 log_a->prop_abs[c] = cur_addr->prop_abs[c];
201 log_a->prop_norm[c] = cur_addr->prop_norm[c];
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "\t %s = %.2f %.2f [abs/rel]\n",
204 GNUNET_ATS_print_property_type(c),
206 log_a->prop_norm[c]);
208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in);
210 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "\t BW out = %llu\n", log_a->assigned_bw_out);
212 GNUNET_CONTAINER_DLL_insert_tail (log_p->addr_head, log_p->addr_tail, log_a);
219 logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
221 struct LoggingHandle *l = cls;
223 l->logging_task = NULL;
224 GNUNET_ATS_solver_logging_now (l);
225 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq,
230 struct LoggingHandle *
231 GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
233 struct LoggingHandle *l;
234 l = GNUNET_new (struct LoggingHandle);
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
237 GNUNET_STRINGS_relative_time_to_string(freq, GNUNET_NO));
239 l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
244 GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
246 if (NULL != l->logging_task)
247 GNUNET_SCHEDULER_cancel (l->logging_task);
249 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
251 l->logging_task = NULL;
254 static struct LoggingFileHandle *
255 find_logging_file_handle (struct LoggingFileHandle *lf_head,
256 struct LoggingFileHandle *lf_tail,
257 int peer_id, int address_id)
259 struct LoggingFileHandle *res;
261 for (res = lf_head; NULL != res; res = res->next)
262 if ((res->pid == peer_id) && (res->aid == address_id))
269 GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int add_time_stamp,
272 struct LoggingTimeStep *lts;
273 struct LoggingPeer *log_p;
274 struct LoggingAddress *log_a;
275 struct LoggingFileHandle *lf_head;
276 struct LoggingFileHandle *lf_tail;
277 struct LoggingFileHandle *cur;
278 struct LoggingFileHandle *next;
282 char * propstring_tmp;
284 char * prefstring_tmp;
289 if (NULL != output_dir)
291 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (output_dir))
293 fprintf (stderr, "Failed to create directory `%s'\n", output_dir);
298 fprintf (stderr, "Created directory `%s'\n", output_dir);
299 use_dir = GNUNET_YES;
306 for (lts = l->head; NULL != lts; lts = lts->next)
309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing log step %llu\n",
310 (long long unsigned int) lts->timestamp.abs_value_us);
312 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
314 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
317 cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
321 cur = GNUNET_new (struct LoggingFileHandle);
322 cur->aid = log_a->aid;
323 cur->pid = log_p->id;
325 if (GNUNET_YES == add_time_stamp)
326 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u_%llu.log",
327 (GNUNET_YES == use_dir) ? output_dir : "",
328 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
333 l->head->timestamp.abs_value_us);
335 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u.log",
336 (GNUNET_YES == use_dir) ? output_dir : "",
337 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
343 fprintf (stderr, "Add writing log data for peer %llu address %llu to file `%s'\n",
344 cur->pid, cur->aid, filename);
347 cur->f_hd = GNUNET_DISK_file_open (filename,
348 GNUNET_DISK_OPEN_READWRITE |
349 GNUNET_DISK_OPEN_CREATE |
350 GNUNET_DISK_OPEN_TRUNCATE,
351 GNUNET_DISK_PERM_USER_READ |
352 GNUNET_DISK_PERM_USER_WRITE |
353 GNUNET_DISK_PERM_GROUP_READ |
354 GNUNET_DISK_PERM_OTHER_READ);
355 if (NULL == cur->f_hd)
357 fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
358 GNUNET_free (filename);
362 GNUNET_free (filename);
363 GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
365 GNUNET_asprintf(&datastring,"#time delta;log duration;peer_requested;addr net; addr_active; bw in; bw out; " \
366 "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
367 "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;"\
369 "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
370 "COST_WLAN; COST_WLAN;COST_BT; COST_BT; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n");
371 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
372 GNUNET_free (datastring);
376 prefstring = GNUNET_strdup("");
377 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
380 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
381 GNUNET_ATS_print_preference_type(c),
382 log_p->pref_abs[c], log_p->pref_norm[c]);
384 GNUNET_asprintf(&prefstring_tmp,"%s;%.3f;%.3f",
385 prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
388 GNUNET_free (prefstring);
389 prefstring = GNUNET_strdup(prefstring_tmp);
390 GNUNET_free (prefstring_tmp);
394 propstring = GNUNET_strdup("");
395 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
397 if (GNUNET_ATS_NETWORK_TYPE == c)
400 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
401 GNUNET_ATS_print_property_type(c),
402 log_a->prop_abs[c], log_a->prop_norm[c]);*/
403 GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;",
406 log_a->prop_norm[c]);
407 GNUNET_free (propstring);
408 propstring = GNUNET_strdup(propstring_tmp);
409 GNUNET_free (propstring_tmp);
411 GNUNET_asprintf (&datastring, "%llu;%llu;%u;%u;%i;%u;%u;%s;%s\n",
412 GNUNET_TIME_absolute_get_difference (l->head->timestamp,
413 lts->timestamp).rel_value_us / 1000, lts->delta,
414 log_p->is_requested, log_a->network, log_a->active,
415 log_a->assigned_bw_in, log_a->assigned_bw_out, propstring,
418 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
419 GNUNET_free (datastring);
420 GNUNET_free (prefstring);
421 GNUNET_free (propstring);
428 for (cur = next; NULL != cur; cur = next)
431 GNUNET_CONTAINER_DLL_remove (lf_head, lf_tail, cur);
432 if (NULL != cur->f_hd)
433 GNUNET_DISK_file_close (cur->f_hd);
440 GNUNET_ATS_solver_logging_eval (struct LoggingHandle *l)
442 struct LoggingTimeStep *lts;
443 struct LoggingPeer *log_p;
444 struct LoggingAddress *log_a;
447 for (lts = l->head; NULL != lts; lts = lts->next)
449 fprintf (stderr, "Log step %llu %llu: \n",
450 (long long unsigned int) lts->timestamp.abs_value_us,
451 (long long unsigned int) lts->delta.rel_value_us);
453 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
455 fprintf (stderr,"\tLogging peer pid %llu\n", log_p->id);
456 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
458 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
459 GNUNET_ATS_print_preference_type(c),
460 log_p->pref_abs[c], log_p->pref_norm[c]);
463 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
465 fprintf (stderr, "\tPeer pid %llu address %llu: %u %u %u\n",
466 log_p->id, log_a->aid, log_a->active,
467 log_a->assigned_bw_in,
468 log_a->assigned_bw_out);
470 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
472 if (GNUNET_ATS_NETWORK_TYPE == c)
474 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
475 GNUNET_ATS_print_property_type(c),
476 log_a->prop_abs[c], log_a->prop_norm[c]);
484 GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
486 struct LoggingTimeStep *lts_cur;
487 struct LoggingTimeStep *lts_next;
488 struct LoggingPeer *log_p_cur;
489 struct LoggingPeer *log_p_next;
490 struct LoggingAddress *log_a_cur;
491 struct LoggingAddress *log_a_next;
493 if (NULL != l->logging_task)
494 GNUNET_SCHEDULER_cancel (l->logging_task);
495 l->logging_task = NULL;
498 while (NULL != (lts_cur = lts_next))
500 lts_next = lts_cur->next;
502 log_p_next = lts_cur->head;
503 while (NULL != (log_p_cur = log_p_next))
505 log_p_next = log_p_cur->next;
507 log_a_next = log_p_cur->addr_head;
508 while (NULL != (log_a_cur = log_a_next))
510 log_a_next = log_a_cur->next;
512 GNUNET_CONTAINER_DLL_remove (log_p_cur->addr_head, log_p_cur->addr_tail, log_a_cur);
513 GNUNET_free (log_a_cur);
516 GNUNET_CONTAINER_DLL_remove (lts_cur->head, lts_cur->tail, log_p_cur);
517 GNUNET_free (log_p_cur);
520 GNUNET_CONTAINER_DLL_remove (l->head, l->tail, lts_cur);
521 GNUNET_free (lts_cur);
528 * Property Generators
530 static struct PropertyGenerator *prop_gen_head;
531 static struct PropertyGenerator *prop_gen_tail;
535 get_property (struct PropertyGenerator *pg)
537 struct GNUNET_TIME_Relative time_delta;
541 /* Calculate the current preference value */
543 case GNUNET_ATS_TEST_TG_CONSTANT:
544 pref_value = pg->base_value;
546 case GNUNET_ATS_TEST_TG_LINEAR:
547 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
548 /* Calculate point of time in the current period */
549 time_delta.rel_value_us = time_delta.rel_value_us %
550 pg->duration_period.rel_value_us;
551 delta_value = ((double) time_delta.rel_value_us /
552 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
553 if ((pg->max_value < pg->base_value) &&
554 ((pg->max_value - pg->base_value) > pg->base_value))
556 /* This will cause an underflow */
559 pref_value = pg->base_value + delta_value;
561 case GNUNET_ATS_TEST_TG_RANDOM:
562 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
563 10000 * (pg->max_value - pg->base_value)) / 10000;
564 pref_value = pg->base_value + delta_value;
566 case GNUNET_ATS_TEST_TG_SINUS:
567 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
568 /* Calculate point of time in the current period */
569 time_delta.rel_value_us = time_delta.rel_value_us %
570 pg->duration_period.rel_value_us;
571 if ((pg->max_value - pg->base_value) > pg->base_value)
573 /* This will cause an underflow for second half of sinus period,
574 * will be detected in general when experiments are loaded */
577 delta_value = (pg->max_value - pg->base_value) *
578 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
579 time_delta.rel_value_us);
580 pref_value = pg->base_value + delta_value;
586 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current property value is %f\n",
593 set_prop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
595 struct PropertyGenerator *pg = cls;
597 struct TestAddress *a;
599 struct GNUNET_ATS_Information atsi;
603 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains_value (sh->addresses,
604 &pg->test_peer->peer_id, pg->test_address->ats_addr))
607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
608 "Setting property generation for unknown address [%u:%u]\n",
609 pg->peer, pg->address_id);
612 if (NULL == (p = find_peer_by_id (pg->peer)))
615 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
616 "Setting property generation for unknown peer %u\n",
620 if (NULL == (a = find_address_by_id (p, pg->address_id)))
623 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
624 "Setting property generation for unknown peer %u\n",
629 prop_value = get_property (pg);
630 a->prop_abs[pg->ats_property] = prop_value;
632 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
633 "Setting property for peer [%u] address [%u] for %s to %f\n",
634 pg->peer, pg->address_id,
635 GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
637 atsi.type = htonl (pg->ats_property);
638 atsi.value = htonl ((uint32_t) prop_value);
640 /* set performance here! */
641 sh->sf->s_bulk_start (sh->sf->cls);
642 if (GNUNET_YES == opt_disable_normalization)
644 a->prop_abs[pg->ats_property] = prop_value;
645 a->prop_norm[pg->ats_property] = prop_value;
646 sh->sf->s_address_update_property (sh->sf->cls, a->ats_addr,
647 pg->ats_property, prop_value, prop_value);
650 GAS_normalization_update_property (pg->test_address->ats_addr, &atsi, 1);
651 sh->sf->s_bulk_stop (sh->sf->cls);
653 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
659 * Set ats_property to 0 to find all pgs
661 static struct PropertyGenerator *
662 find_prop_gen (unsigned int peer, unsigned int address,
663 uint32_t ats_property)
665 struct PropertyGenerator *cur;
666 for (cur = prop_gen_head; NULL != cur; cur = cur->next)
667 if ((cur->peer == peer) && (cur->address_id == address))
669 if ((cur->ats_property == ats_property) || (0 == ats_property))
676 GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
678 GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
680 if (NULL != pg->set_task)
682 GNUNET_SCHEDULER_cancel (pg->set_task);
685 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
686 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
687 pg->peer, pg->address_id,
688 GNUNET_ATS_print_property_type(pg->ats_property));
695 * Generate between the source master and the partner and set property with a
696 * value depending on the generator.
699 * @param address_id partner
700 * @param test_peer the peer
701 * @param test_address the address
702 * @param type type of generator
703 * @param base_value base value
704 * @param value_rate maximum value
705 * @param period duration of a period of generation (~ 1/frequency)
706 * @param frequency how long to generate property
707 * @param ats_property ATS property to generate
708 * @return the property generator
710 struct PropertyGenerator *
711 GNUNET_ATS_solver_generate_property_start (unsigned int peer,
712 unsigned int address_id,
713 struct TestPeer *test_peer,
714 struct TestAddress *test_address,
715 enum GeneratorType type,
718 struct GNUNET_TIME_Relative period,
719 struct GNUNET_TIME_Relative frequency,
720 uint32_t ats_property)
722 struct PropertyGenerator *pg;
724 pg = GNUNET_new (struct PropertyGenerator);
725 GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
728 pg->test_address = test_address;
729 pg->test_peer = test_peer;
730 pg->address_id = address_id;
731 pg->ats_property = ats_property;
732 pg->base_value = base_value;
733 pg->max_value = value_rate;
734 pg->duration_period = period;
735 pg->frequency = frequency;
736 pg->time_start = GNUNET_TIME_absolute_get();
739 case GNUNET_ATS_TEST_TG_CONSTANT:
740 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
741 "Setting up %s property generator peer [%u] address [%u] `%s'"\
743 print_generator_type(type), pg->peer, pg->address_id,
744 GNUNET_ATS_print_property_type (ats_property),
747 case GNUNET_ATS_TEST_TG_LINEAR:
748 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
749 "Setting up %s property generator peer [%u] address [%u] `%s' " \
750 "min %u Bips max %u Bips\n",
751 print_generator_type(type), pg->peer, pg->address_id,
752 GNUNET_ATS_print_property_type(ats_property),
753 base_value, value_rate);
755 case GNUNET_ATS_TEST_TG_SINUS:
756 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
757 "Setting up %s property generator peer [%u] address [%u] `%s' "\
758 "baserate %u Bips, amplitude %u Bps\n",
759 print_generator_type(type), pg->peer, pg->address_id,
760 GNUNET_ATS_print_property_type(ats_property),
761 base_value, value_rate);
763 case GNUNET_ATS_TEST_TG_RANDOM:
764 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
765 "Setting up %s property generator peer [%u] address [%u] `%s' "\
766 "min %u Bips max %u Bps\n",
767 print_generator_type(type), pg->peer, pg->address_id,
768 GNUNET_ATS_print_property_type(ats_property),
769 base_value, value_rate);
775 pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
781 * Stop all preferences generators
784 GNUNET_ATS_solver_generate_property_stop_all ()
786 struct PropertyGenerator *cur;
787 struct PropertyGenerator *next;
788 next = prop_gen_head;
789 for (cur = next; NULL != cur; cur = next)
792 GNUNET_ATS_solver_generate_property_stop (cur);
798 * Preference Generators
800 static struct PreferenceGenerator *pref_gen_head;
801 static struct PreferenceGenerator *pref_gen_tail;
805 get_preference (struct PreferenceGenerator *pg)
807 struct GNUNET_TIME_Relative time_delta;
811 /* Calculate the current preference value */
813 case GNUNET_ATS_TEST_TG_CONSTANT:
814 pref_value = pg->base_value;
816 case GNUNET_ATS_TEST_TG_LINEAR:
817 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
818 /* Calculate point of time in the current period */
819 time_delta.rel_value_us = time_delta.rel_value_us %
820 pg->duration_period.rel_value_us;
821 delta_value = ((double) time_delta.rel_value_us /
822 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
823 if ((pg->max_value < pg->base_value) &&
824 ((pg->max_value - pg->base_value) > pg->base_value))
826 /* This will cause an underflow */
829 pref_value = pg->base_value + delta_value;
831 case GNUNET_ATS_TEST_TG_RANDOM:
832 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
833 10000 * (pg->max_value - pg->base_value)) / 10000;
834 pref_value = pg->base_value + delta_value;
836 case GNUNET_ATS_TEST_TG_SINUS:
837 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
838 /* Calculate point of time in the current period */
839 time_delta.rel_value_us = time_delta.rel_value_us %
840 pg->duration_period.rel_value_us;
841 if ((pg->max_value - pg->base_value) > pg->base_value)
843 /* This will cause an underflow for second half of sinus period,
844 * will be detected in general when experiments are loaded */
847 delta_value = (pg->max_value - pg->base_value) *
848 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
849 time_delta.rel_value_us);
850 pref_value = pg->base_value + delta_value;
856 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
862 set_feedback_task (void *cls,
863 const struct GNUNET_SCHEDULER_TaskContext *tc)
865 struct PreferenceGenerator *pg = cls;
870 uint32_t delay_acc_in;
871 struct GNUNET_TIME_Relative dur;
874 pg->feedback_task = NULL;
876 if (NULL == (p = find_peer_by_id (pg->peer)))
879 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
880 "Setting feedback for unknown peer %u\n", pg->peer);
886 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
887 dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
888 bw_acc_in = dur.rel_value_us *pg->last_assigned_bw_in + pg->feedback_bw_in_acc;
889 pg->feedback_bw_in_acc = 0;
891 bw_acc_out = dur.rel_value_us *pg->last_assigned_bw_out + pg->feedback_bw_out_acc;
892 p_new = get_preference (pg);
893 feedback = (p_new / pg->pref_bw_old) * (bw_acc_in + bw_acc_out) /
894 (2 *GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
897 case GNUNET_ATS_PREFERENCE_LATENCY:
898 dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_delay_update);
899 delay_acc_in =dur.rel_value_us *pg->last_delay_value + pg->feedback_delay_acc;
900 pg->feedback_delay_acc = 0;
902 p_new = get_preference (pg);
903 feedback = (p_new / pg->pref_latency_old) * (delay_acc_in) /
904 (GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
912 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
913 "Giving feedback for peer [%u] for client %p pref %s of %.3f\n",
914 pg->peer, NULL + (pg->client_id),
915 GNUNET_ATS_print_preference_type (pg->kind),
918 sh->sf->s_feedback (sh->sf->cls, NULL + (pg->client_id), &p->peer_id,
919 pg->feedback_frequency, pg->kind, feedback);
920 pg->feedback_last = GNUNET_TIME_absolute_get();
923 pg->feedback_bw_out_acc = 0;
924 pg->feedback_bw_in_acc = 0;
925 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
927 pg->feedback_delay_acc = 0;
928 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
931 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (pg->feedback_frequency,
932 &set_feedback_task, pg);
937 set_pref_task (void *cls,
938 const struct GNUNET_SCHEDULER_TaskContext *tc)
940 struct PreferenceGenerator *pg = cls;
945 if (NULL == (p = find_peer_by_id (pg->peer)))
948 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
949 "Setting preference for unknown peer %u\n", pg->peer);
953 pref_value = get_preference (pg);
955 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
956 pg->pref_bw_old = pref_value;
958 case GNUNET_ATS_PREFERENCE_LATENCY:
959 pg->pref_latency_old = pref_value;
965 p->pref_abs[pg->kind] = pref_value;
967 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
968 "Setting preference for peer [%u] for client %p pref %s to %f\n",
969 pg->peer, NULL + (pg->client_id),
970 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
972 if (GNUNET_YES == opt_disable_normalization)
974 p->pref_abs[pg->kind] = pref_value;
975 p->pref_norm[pg->kind] = pref_value;
976 sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
979 update_preference (NULL + (pg->client_id),
984 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
990 static struct PreferenceGenerator *
991 find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
993 struct PreferenceGenerator *cur;
994 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
995 if (cur->peer == peer)
997 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
1004 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
1006 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
1008 if (NULL != pg->feedback_task)
1010 GNUNET_SCHEDULER_cancel (pg->feedback_task);
1011 pg->feedback_task = NULL;
1014 if (NULL != pg->set_task)
1016 GNUNET_SCHEDULER_cancel (pg->set_task);
1017 pg->set_task = NULL;
1019 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1020 "Removing old up preference generator peer [%u] `%s'\n",
1021 pg->peer, GNUNET_ATS_print_preference_type(pg->kind));
1027 static struct TestAddress*
1028 find_active_address (struct TestPeer *p)
1030 struct TestAddress *cur;
1031 for (cur = p->addr_head; NULL != cur; cur = cur->next)
1032 if (GNUNET_YES == cur->ats_addr->active)
1039 * Generate between the source master and the partner and set property with a
1040 * value depending on the generator.
1042 * @param peer source
1043 * @param address_id partner
1044 * @param client_id the client
1045 * @param type type of generator
1046 * @param base_value base value
1047 * @param value_rate maximum value
1048 * @param period duration of a period of generation (~ 1/frequency)
1049 * @param frequency how long to generate property
1050 * @param kind ATS preference to generate
1051 * @param feedback_frequency how often to give feedback
1052 * @return the preference generator
1054 struct PreferenceGenerator *
1055 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
1056 unsigned int address_id,
1057 unsigned int client_id,
1058 enum GeneratorType type,
1059 long int base_value,
1060 long int value_rate,
1061 struct GNUNET_TIME_Relative period,
1062 struct GNUNET_TIME_Relative frequency,
1063 enum GNUNET_ATS_PreferenceKind kind,
1064 struct GNUNET_TIME_Relative feedback_frequency)
1066 struct PreferenceGenerator *pg;
1069 if (NULL == (p = find_peer_by_id (peer)))
1072 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1073 "Starting preference for unknown peer %u\n", peer);
1077 pg = GNUNET_new (struct PreferenceGenerator);
1078 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
1081 pg->client_id = client_id;
1083 pg->base_value = base_value;
1084 pg->max_value = value_rate;
1085 pg->duration_period = period;
1086 pg->frequency = frequency;
1087 pg->time_start = GNUNET_TIME_absolute_get();
1088 pg->feedback_frequency = feedback_frequency;
1091 case GNUNET_ATS_TEST_TG_CONSTANT:
1092 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1093 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
1094 print_generator_type (type), pg->peer,
1095 GNUNET_ATS_print_preference_type(kind),
1098 case GNUNET_ATS_TEST_TG_LINEAR:
1099 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1100 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
1101 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1102 base_value, value_rate);
1104 case GNUNET_ATS_TEST_TG_SINUS:
1105 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1106 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
1107 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1108 base_value, value_rate);
1110 case GNUNET_ATS_TEST_TG_RANDOM:
1111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1112 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1113 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1114 base_value, value_rate);
1120 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1121 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != feedback_frequency.rel_value_us)
1123 struct TestAddress * addr = find_active_address(p);
1125 pg->last_assigned_bw_in = p->assigned_bw_in;
1126 pg->last_assigned_bw_out = p->assigned_bw_out;
1127 pg->feedback_bw_in_acc = 0;
1128 pg->feedback_bw_out_acc = 0;
1129 pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
1130 pg->feedback_delay_acc = 0;
1132 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
1133 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
1134 pg->feedback_last = GNUNET_TIME_absolute_get();
1135 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
1136 &set_feedback_task, pg);
1145 * Stop all preferences generators
1148 GNUNET_ATS_solver_generate_preferences_stop_all ()
1150 struct PreferenceGenerator *cur;
1151 struct PreferenceGenerator *next;
1152 next = pref_gen_head;
1153 for (cur = next; NULL != cur; cur = next)
1156 GNUNET_ATS_solver_generate_preferences_stop(cur);
1166 print_op (enum OperationType op)
1169 case SOLVER_OP_ADD_ADDRESS:
1170 return "ADD_ADDRESS";
1171 case SOLVER_OP_DEL_ADDRESS:
1172 return "DEL_ADDRESS";
1173 case SOLVER_OP_START_SET_PREFERENCE:
1174 return "START_SET_PREFERENCE";
1175 case SOLVER_OP_STOP_SET_PREFERENCE:
1176 return "STOP_STOP_PREFERENCE";
1177 case SOLVER_OP_START_SET_PROPERTY:
1178 return "START_SET_PROPERTY";
1179 case SOLVER_OP_STOP_SET_PROPERTY:
1180 return "STOP_SET_PROPERTY";
1181 case SOLVER_OP_START_REQUEST:
1182 return "START_REQUEST";
1183 case SOLVER_OP_STOP_REQUEST:
1184 return "STOP_REQUEST";
1192 static struct Experiment *
1193 create_experiment ()
1195 struct Experiment *e;
1196 e = GNUNET_new (struct Experiment);
1199 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1205 free_experiment (struct Experiment *e)
1207 struct Episode *cur;
1208 struct Episode *next;
1209 struct GNUNET_ATS_TEST_Operation *cur_o;
1210 struct GNUNET_ATS_TEST_Operation *next_o;
1213 for (cur = next; NULL != cur; cur = next)
1218 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1220 next_o = cur_o->next;
1221 GNUNET_free_non_null (cur_o->address);
1222 GNUNET_free_non_null (cur_o->plugin);
1223 GNUNET_free (cur_o);
1228 GNUNET_free_non_null (e->name);
1229 GNUNET_free_non_null (e->log_prefix);
1230 GNUNET_free_non_null (e->log_output_dir);
1231 GNUNET_free_non_null (e->cfg_file);
1237 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1241 const struct GNUNET_CONFIGURATION_Handle *cfg)
1247 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1248 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1249 sec_name, op_name, &o->peer_id))
1251 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1252 op_counter, "ADD_ADDRESS", op_name);
1253 GNUNET_free (op_name);
1254 return GNUNET_SYSERR;
1256 GNUNET_free (op_name);
1259 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1260 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1261 sec_name, op_name, &o->address_id))
1263 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1264 op_counter, "ADD_ADDRESS", op_name);
1265 GNUNET_free (op_name);
1266 return GNUNET_SYSERR;
1268 GNUNET_free (op_name);
1271 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1272 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1273 sec_name, op_name, &o->plugin))
1275 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1276 op_counter, "ADD_ADDRESS", op_name);
1277 GNUNET_free (op_name);
1278 return GNUNET_SYSERR;
1280 GNUNET_free (op_name);
1283 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1284 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1285 sec_name, op_name, &o->address))
1287 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1288 op_counter, "ADD_ADDRESS", op_name);
1289 GNUNET_free (op_name);
1290 return GNUNET_SYSERR;
1292 GNUNET_free (op_name);
1295 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1296 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1297 sec_name, op_name, &o->address_session))
1299 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1300 op_counter, "ADD_ADDRESS", op_name);
1301 GNUNET_free (op_name);
1302 return GNUNET_SYSERR;
1304 GNUNET_free (op_name);
1307 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
1308 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1309 sec_name, op_name, &op_network))
1311 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
1312 op_counter, "ADD_ADDRESS", op_name);
1313 GNUNET_free (op_name);
1314 return GNUNET_SYSERR;
1318 GNUNET_STRINGS_utf8_toupper (op_network,op_network);
1319 if (0 == strcmp(op_network, "UNSPECIFIED"))
1321 o->address_network = GNUNET_ATS_NET_UNSPECIFIED;
1323 else if (0 == strcmp(op_network, "LOOPBACK"))
1325 o->address_network = GNUNET_ATS_NET_LOOPBACK;
1327 else if (0 == strcmp(op_network, "LAN"))
1329 o->address_network = GNUNET_ATS_NET_LAN;
1331 else if (0 == strcmp(op_network, "WAN"))
1333 o->address_network = GNUNET_ATS_NET_WAN;
1335 else if (0 == strcmp(op_network, "WLAN"))
1337 o->address_network = GNUNET_ATS_NET_WLAN;
1339 else if (0 == strcmp(op_network, "BT"))
1341 o->address_network = GNUNET_ATS_NET_BT;
1345 fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1346 op_counter, "ADD_ADDRESS", op_name, op_network);
1347 GNUNET_free (op_network);
1348 GNUNET_free (op_name);
1349 return GNUNET_SYSERR;
1352 GNUNET_free (op_network);
1353 GNUNET_free (op_name);
1355 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1356 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1357 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1364 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1368 const struct GNUNET_CONFIGURATION_Handle *cfg)
1374 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1375 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1376 sec_name, op_name, &o->peer_id))
1378 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1379 op_counter, "DEL_ADDRESS", op_name);
1380 GNUNET_free (op_name);
1381 return GNUNET_SYSERR;
1383 GNUNET_free (op_name);
1386 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1387 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1388 sec_name, op_name, &o->address_id))
1390 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1391 op_counter, "DEL_ADDRESS", op_name);
1392 GNUNET_free (op_name);
1393 return GNUNET_SYSERR;
1395 GNUNET_free (op_name);
1399 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1400 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1401 sec_name, op_name, &o->plugin))
1403 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1404 op_counter, "DEL_ADDRESS", op_name);
1405 GNUNET_free (op_name);
1406 return GNUNET_SYSERR;
1408 GNUNET_free (op_name);
1411 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1412 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1413 sec_name, op_name, &o->address))
1415 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1416 op_counter, "DEL_ADDRESS", op_name);
1417 GNUNET_free (op_name);
1418 return GNUNET_SYSERR;
1420 GNUNET_free (op_name);
1423 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1424 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1425 sec_name, op_name, &o->address_session))
1427 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1428 op_counter, "DEL_ADDRESS", op_name);
1429 GNUNET_free (op_name);
1430 return GNUNET_SYSERR;
1432 GNUNET_free (op_name);
1435 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1436 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1437 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1443 static enum GNUNET_ATS_Property
1444 parse_preference_string (const char * str)
1447 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1449 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1450 if (0 == strcmp(str, props[c]))
1457 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1461 const struct GNUNET_CONFIGURATION_Handle *cfg)
1468 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1469 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1470 sec_name, op_name, &o->peer_id))
1472 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1473 op_counter, "START_SET_PREFERENCE", op_name);
1474 GNUNET_free (op_name);
1475 return GNUNET_SYSERR;
1477 GNUNET_free (op_name);
1480 GNUNET_asprintf(&op_name, "op-%u-client-id", op_counter);
1481 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1482 sec_name, op_name, &o->client_id))
1484 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1485 op_counter, "START_SET_PREFERENCE", op_name);
1486 GNUNET_free (op_name);
1487 return GNUNET_SYSERR;
1489 GNUNET_free (op_name);
1492 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1493 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1494 sec_name, op_name, &type)) )
1496 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1497 op_counter, "START_SET_PREFERENCE", op_name);
1498 GNUNET_free (op_name);
1499 return GNUNET_SYSERR;
1502 /* Load arguments for set_rate, start_send, set_preference */
1503 if (0 == strcmp (type, "constant"))
1505 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1507 else if (0 == strcmp (type, "linear"))
1509 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1511 else if (0 == strcmp (type, "sinus"))
1513 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1515 else if (0 == strcmp (type, "random"))
1517 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1521 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1522 op_counter, op_name, e->id);
1524 GNUNET_free (op_name);
1525 return GNUNET_SYSERR;
1528 GNUNET_free (op_name);
1532 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1533 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1534 sec_name, op_name, &o->base_rate))
1536 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1537 op_counter, op_name, e->id);
1538 GNUNET_free (op_name);
1539 return GNUNET_SYSERR;
1541 GNUNET_free (op_name);
1545 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1546 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1547 sec_name, op_name, &o->max_rate))
1549 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1550 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1551 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1553 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1554 op_counter, op_name, e->id);
1555 GNUNET_free (op_name);
1556 return GNUNET_SYSERR;
1559 GNUNET_free (op_name);
1562 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1563 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1564 sec_name, op_name, &o->period))
1566 o->period = e->duration;
1568 GNUNET_free (op_name);
1571 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1572 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1573 sec_name, op_name, &o->frequency))
1575 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1576 op_counter, op_name, e->id);
1577 GNUNET_free (op_name);
1578 return GNUNET_SYSERR;
1580 GNUNET_free (op_name);
1582 /* Get preference */
1583 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1584 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1585 sec_name, op_name, &pref))
1587 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1588 op_counter, op_name, e->id);
1589 GNUNET_free (op_name);
1590 return GNUNET_SYSERR;
1593 if (0 == (o->pref_type = parse_preference_string(pref)))
1595 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1596 op_counter, op_name, e->id);
1597 GNUNET_free (op_name);
1599 return GNUNET_SYSERR;
1602 GNUNET_free (op_name);
1604 /* Get feedback delay */
1605 GNUNET_asprintf(&op_name, "op-%u-feedback_delay", op_counter);
1606 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
1607 sec_name, op_name, &o->feedback_delay))
1609 fprintf (stderr, "Using feedback delay %llu in operation %u `%s' in episode %u\n",
1610 (long long unsigned int) o->feedback_delay.rel_value_us,
1611 op_counter, op_name, e->id);
1614 o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
1615 GNUNET_free (op_name);
1617 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1618 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1619 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1620 GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
1627 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1631 const struct GNUNET_CONFIGURATION_Handle *cfg)
1637 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1638 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1639 sec_name, op_name, &o->peer_id))
1641 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1642 op_counter, "STOP_SET_PREFERENCE", op_name);
1643 GNUNET_free (op_name);
1644 return GNUNET_SYSERR;
1646 GNUNET_free (op_name);
1649 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1650 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1651 sec_name, op_name, &o->address_id))
1653 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1654 op_counter, "STOP_SET_PREFERENCE", op_name);
1655 GNUNET_free (op_name);
1656 return GNUNET_SYSERR;
1658 GNUNET_free (op_name);
1660 /* Get preference */
1661 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1662 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1663 sec_name, op_name, &pref))
1665 fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
1666 op_counter, "STOP_SET_PREFERENCE", op_name);
1667 GNUNET_free (op_name);
1668 return GNUNET_SYSERR;
1671 if (0 == (o->pref_type = parse_preference_string(pref)))
1673 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1674 op_counter, op_name, e->id);
1675 GNUNET_free (op_name);
1677 return GNUNET_SYSERR;
1680 GNUNET_free (op_name);
1682 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1683 "Found operation %s: [%llu:%llu]: %s\n",
1684 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1685 GNUNET_ATS_print_preference_type(o->pref_type));
1690 static enum GNUNET_ATS_Property
1691 parse_property_string (const char *str)
1693 enum GNUNET_ATS_Property c;
1695 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1696 if (0 == strcmp(str,
1697 GNUNET_ATS_print_property_type (c)))
1704 load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
1708 const struct GNUNET_CONFIGURATION_Handle *cfg)
1715 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1716 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1717 sec_name, op_name, &o->peer_id))
1719 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1720 op_counter, "START_SET_PROPERTY", op_name);
1721 GNUNET_free (op_name);
1722 return GNUNET_SYSERR;
1724 GNUNET_free (op_name);
1727 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1728 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1729 sec_name, op_name, &o->address_id))
1731 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1732 op_counter, "START_SET_PROPERTY", op_name);
1733 GNUNET_free (op_name);
1734 return GNUNET_SYSERR;
1736 GNUNET_free (op_name);
1739 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1740 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1741 sec_name, op_name, &type)) )
1743 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1744 op_counter, "START_SET_PROPERTY", op_name);
1745 GNUNET_free (op_name);
1746 return GNUNET_SYSERR;
1749 /* Load arguments for set_rate, start_send, set_preference */
1750 if (0 == strcmp (type, "constant"))
1752 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1754 else if (0 == strcmp (type, "linear"))
1756 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1758 else if (0 == strcmp (type, "sinus"))
1760 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1762 else if (0 == strcmp (type, "random"))
1764 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1768 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1769 op_counter, op_name, e->id);
1771 GNUNET_free (op_name);
1772 return GNUNET_SYSERR;
1775 GNUNET_free (op_name);
1779 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1780 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1781 sec_name, op_name, &o->base_rate))
1783 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1784 op_counter, op_name, e->id);
1785 GNUNET_free (op_name);
1786 return GNUNET_SYSERR;
1788 GNUNET_free (op_name);
1792 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1793 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1794 sec_name, op_name, &o->max_rate))
1796 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1797 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1798 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1800 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1801 op_counter, op_name, e->id);
1802 GNUNET_free (op_name);
1803 return GNUNET_SYSERR;
1806 GNUNET_free (op_name);
1809 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1810 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1811 sec_name, op_name, &o->period))
1813 o->period = e->duration;
1815 GNUNET_free (op_name);
1818 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1819 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1820 sec_name, op_name, &o->frequency))
1822 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1823 op_counter, op_name, e->id);
1824 GNUNET_free (op_name);
1825 return GNUNET_SYSERR;
1827 GNUNET_free (op_name);
1829 /* Get preference */
1830 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1831 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1832 sec_name, op_name, &prop))
1834 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1835 op_counter, op_name, e->id);
1836 GNUNET_free (op_name);
1837 GNUNET_free_non_null (prop);
1838 return GNUNET_SYSERR;
1841 if (0 == (o->prop_type = parse_property_string(prop)))
1843 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1844 op_counter, op_name, e->id);
1845 GNUNET_free (op_name);
1847 return GNUNET_SYSERR;
1851 GNUNET_free (op_name);
1853 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1854 "Found operation %s: [%llu:%llu] %s = %llu\n",
1855 "START_SET_PROPERTY", o->peer_id, o->address_id,
1856 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1862 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1866 const struct GNUNET_CONFIGURATION_Handle *cfg)
1872 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1873 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1874 sec_name, op_name, &o->peer_id))
1876 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1877 op_counter, "STOP_SET_PROPERTY", op_name);
1878 GNUNET_free (op_name);
1879 return GNUNET_SYSERR;
1881 GNUNET_free (op_name);
1884 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1885 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1886 sec_name, op_name, &o->address_id))
1888 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1889 op_counter, "STOP_SET_PROPERTY", op_name);
1890 GNUNET_free (op_name);
1891 return GNUNET_SYSERR;
1893 GNUNET_free (op_name);
1896 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1897 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1898 sec_name, op_name, &pref))
1900 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
1901 op_counter, "STOP_SET_PROPERTY", op_name);
1902 GNUNET_free (op_name);
1903 GNUNET_free_non_null (pref);
1904 return GNUNET_SYSERR;
1907 if (0 == (o->prop_type = parse_property_string(pref)))
1909 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1910 op_counter, op_name, e->id);
1911 GNUNET_free (op_name);
1912 GNUNET_free_non_null (pref);
1913 return GNUNET_SYSERR;
1917 GNUNET_free (op_name);
1919 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1920 "Found operation %s: [%llu:%llu] %s\n",
1921 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
1922 GNUNET_ATS_print_property_type (o->prop_type));
1929 load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
1933 const struct GNUNET_CONFIGURATION_Handle *cfg)
1938 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1939 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1940 sec_name, op_name, &o->peer_id))
1942 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1943 op_counter, "START_REQUEST", op_name);
1944 GNUNET_free (op_name);
1945 return GNUNET_SYSERR;
1947 GNUNET_free (op_name);
1952 load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
1956 const struct GNUNET_CONFIGURATION_Handle *cfg)
1961 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1962 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1963 sec_name, op_name, &o->peer_id))
1965 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1966 op_counter, "STOP_REQUEST", op_name);
1967 GNUNET_free (op_name);
1968 return GNUNET_SYSERR;
1970 GNUNET_free (op_name);
1976 load_episode (struct Experiment *e, struct Episode *cur,
1977 struct GNUNET_CONFIGURATION_Handle *cfg)
1979 struct GNUNET_ATS_TEST_Operation *o;
1985 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n",cur->id);
1986 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
1990 /* Load operation */
1991 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
1992 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1993 sec_name, op_name, &op))
1995 GNUNET_free (op_name);
1998 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
1999 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
2002 /* operations = set_rate, start_send, stop_send, set_preference */
2003 if (0 == strcmp (op, "address_add"))
2005 o->type = SOLVER_OP_ADD_ADDRESS;
2006 res = load_op_add_address (o, cur,
2007 op_counter, sec_name, cfg);
2009 else if (0 == strcmp (op, "address_del"))
2011 o->type = SOLVER_OP_DEL_ADDRESS;
2012 res = load_op_del_address (o, cur,
2013 op_counter, sec_name, cfg);
2015 else if (0 == strcmp (op, "start_set_property"))
2017 o->type = SOLVER_OP_START_SET_PROPERTY;
2018 res = load_op_start_set_property (o, cur,
2019 op_counter, sec_name, cfg);
2021 else if (0 == strcmp (op, "stop_set_property"))
2023 o->type = SOLVER_OP_STOP_SET_PROPERTY;
2024 res = load_op_stop_set_property (o, cur,
2025 op_counter, sec_name, cfg);
2027 else if (0 == strcmp (op, "start_set_preference"))
2029 o->type = SOLVER_OP_START_SET_PREFERENCE;
2030 res = load_op_start_set_preference (o, cur,
2031 op_counter, sec_name, cfg);
2033 else if (0 == strcmp (op, "stop_set_preference"))
2035 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
2036 res = load_op_stop_set_preference (o, cur,
2037 op_counter, sec_name, cfg);
2039 else if (0 == strcmp (op, "start_request"))
2041 o->type = SOLVER_OP_START_REQUEST;
2042 res = load_op_start_request (o, cur,
2043 op_counter, sec_name, cfg);
2045 else if (0 == strcmp (op, "stop_request"))
2047 o->type = SOLVER_OP_STOP_REQUEST;
2048 res = load_op_stop_request(o, cur,
2049 op_counter, sec_name, cfg);
2053 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
2054 op_counter, op, cur->id);
2055 res = GNUNET_SYSERR;
2059 GNUNET_free (op_name);
2061 if (GNUNET_SYSERR == res)
2064 GNUNET_free (sec_name);
2065 return GNUNET_SYSERR;
2068 GNUNET_CONTAINER_DLL_insert_tail (cur->head,cur->tail, o);
2071 GNUNET_free (sec_name);
2076 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
2080 struct GNUNET_TIME_Relative e_duration;
2081 struct Episode *cur;
2082 struct Episode *last;
2088 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
2089 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
2090 sec_name, "duration", &e_duration))
2092 GNUNET_free (sec_name);
2096 cur = GNUNET_new (struct Episode);
2097 cur->duration = e_duration;
2098 cur->id = e_counter;
2100 if (GNUNET_OK != load_episode (e, cur, cfg))
2102 GNUNET_free (sec_name);
2104 return GNUNET_SYSERR;
2107 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2109 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
2111 /* Update experiment */
2113 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
2114 /* Put in linked list */
2120 GNUNET_free (sec_name);
2128 timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
2130 struct Experiment *e = cls;
2131 e->experiment_timeout_task = NULL;
2132 fprintf (stderr, "Experiment timeout!\n");
2134 if (NULL != e->episode_timeout_task)
2136 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2137 e->episode_timeout_task = NULL;
2140 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
2144 struct ATS_Address *
2145 create_ats_address (const struct GNUNET_PeerIdentity *peer,
2146 const char *plugin_name,
2147 const void *plugin_addr,
2148 size_t plugin_addr_len,
2149 uint32_t session_id,
2152 struct ATS_Address *aa = NULL;
2154 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len + strlen (plugin_name) + 1);
2155 aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
2156 aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
2157 aa->atsi[0].value = htonl (network);
2161 aa->addr_len = plugin_addr_len;
2163 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2164 memcpy (&aa[1], plugin_addr, plugin_addr_len);
2165 memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2166 aa->session_id = session_id;
2174 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2177 struct TestAddress *a;
2180 if (NULL == (p = find_peer_by_id (op->peer_id)))
2182 p = GNUNET_new (struct TestPeer);
2183 p->id = op->peer_id;
2184 p->assigned_bw_in = 0;
2185 p->assigned_bw_out = 0;
2186 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2187 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2189 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2190 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2193 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2196 if (NULL != (find_address_by_id (p, op->address_id)))
2198 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2199 op->address_id, op->peer_id);
2203 a = GNUNET_new (struct TestAddress);
2204 a->aid = op->address_id;
2205 a->network = op->address_network;
2206 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2207 strlen (op->address) + 1, op->address_session, op->address_network);
2208 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2209 GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
2211 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2212 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2214 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2215 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2217 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding address %u for peer %u in network `%s'\n",
2218 op->address_id, op->peer_id, GNUNET_ATS_print_network_type(a->network));
2220 sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
2226 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2229 struct TestAddress *a;
2230 struct PropertyGenerator *pg;
2232 if (NULL == (p = find_peer_by_id (op->peer_id)))
2235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2236 "Deleting address for unknown peer %u\n", op->peer_id);
2240 if (NULL == (a =find_address_by_id (p, op->address_id)))
2243 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2244 "Deleting address for unknown peer %u\n", op->peer_id);
2248 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2250 GNUNET_ATS_solver_generate_property_stop (pg);
2253 GNUNET_assert (GNUNET_YES ==
2254 GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
2257 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2258 "Removing address %u for peer %u\n",
2262 sh->sf->s_del (sh->sf->cls, a->ats_addr);
2266 GNUNET_ATS_solver_logging_now (l);
2268 GNUNET_CONTAINER_DLL_remove(p->addr_head, p->addr_tail, a);
2270 GNUNET_free_non_null(a->ats_addr->atsi);
2271 GNUNET_free (a->ats_addr);
2277 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2279 struct PropertyGenerator *pg;
2281 struct TestAddress *a;
2283 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2285 GNUNET_ATS_solver_generate_property_stop (pg);
2289 if (NULL == (p = find_peer_by_id (op->peer_id)))
2292 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2293 "Starting property generation for unknown peer %u\n", op->peer_id);
2297 if (NULL == (a = find_address_by_id (p, op->address_id)))
2300 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2301 "Setting property for unknown address %u\n", op->peer_id);
2305 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2317 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2319 struct PropertyGenerator *pg = find_prop_gen(op->peer_id, op->address_id,
2323 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2324 "Stopping preference generation for peer %u address %u\n", op->peer_id,
2326 GNUNET_ATS_solver_generate_property_stop (pg);
2330 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2331 "Cannot find preference generator for peer %u address %u\n",
2332 op->peer_id, op->address_id);
2338 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2340 struct PreferenceGenerator *pg;
2341 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2343 GNUNET_ATS_solver_generate_preferences_stop (pg);
2347 if (NULL == (find_peer_by_id (op->peer_id)))
2350 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2351 "Starting preference generation for unknown peer %u\n", op->peer_id);
2355 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2368 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2370 struct PreferenceGenerator *pg = find_pref_gen(op->peer_id,
2374 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2375 "Stopping property generation for peer %u address %u\n", op->peer_id,
2377 GNUNET_ATS_solver_generate_preferences_stop (pg);
2381 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2382 "Cannot find preference generator for peer %u address %u\n",
2383 op->peer_id, op->address_id);
2390 enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2394 if (NULL == (p = find_peer_by_id (op->peer_id)))
2397 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2398 "Requesting address for unknown peer %u\n", op->peer_id);
2402 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2404 p->is_requested = GNUNET_YES;
2406 sh->sf->s_get (sh->sf->cls, &p->peer_id);
2411 enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
2415 if (NULL == (p = find_peer_by_id (op->peer_id)))
2418 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2419 "Requesting address for unknown peer %u\n", op->peer_id);
2423 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2424 "Stop requesting address for peer %u\n",
2426 p->is_requested = GNUNET_NO;
2427 p->assigned_bw_in = 0;
2428 p->assigned_bw_out = 0;
2429 sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
2433 GNUNET_ATS_solver_logging_now (l);
2438 static void enforce_episode (struct Episode *ep)
2440 struct GNUNET_ATS_TEST_Operation *cur;
2441 for (cur = ep->head; NULL != cur; cur = cur->next)
2443 switch (cur->type) {
2444 case SOLVER_OP_ADD_ADDRESS:
2445 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2446 print_op (cur->type), cur->peer_id, cur->address_id);
2447 enforce_add_address (cur);
2449 case SOLVER_OP_DEL_ADDRESS:
2450 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2451 print_op (cur->type), cur->peer_id, cur->address_id);
2452 enforce_del_address (cur);
2454 case SOLVER_OP_START_SET_PROPERTY:
2455 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2456 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2457 enforce_start_property (cur);
2459 case SOLVER_OP_STOP_SET_PROPERTY:
2460 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2461 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2462 enforce_stop_property (cur);
2464 case SOLVER_OP_START_SET_PREFERENCE:
2465 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2466 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2467 enforce_start_preference (cur);
2469 case SOLVER_OP_STOP_SET_PREFERENCE:
2470 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2471 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2472 enforce_stop_preference (cur);
2474 case SOLVER_OP_START_REQUEST:
2475 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2476 print_op (cur->type), cur->peer_id);
2477 enforce_start_request (cur);
2479 case SOLVER_OP_STOP_REQUEST:
2480 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2481 print_op (cur->type), cur->peer_id);
2482 enforce_stop_request (cur);
2491 timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
2493 struct Experiment *e = cls;
2494 e->episode_timeout_task = NULL;
2495 if (NULL != e->ep_done_cb)
2496 e->ep_done_cb (e->cur);
2498 /* Scheduling next */
2499 e->cur = e->cur->next;
2503 fprintf (stderr, "Last episode done!\n");
2504 if (NULL != e->experiment_timeout_task)
2506 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2507 e->experiment_timeout_task = NULL;
2509 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
2513 fprintf (stderr, "Running episode %u with timeout %s\n",
2515 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2516 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2517 &timeout_episode, e);
2518 enforce_episode(e->cur);
2525 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2526 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
2527 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
2529 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2530 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
2531 e->e_done_cb = e_done_cb;
2532 e->ep_done_cb = ep_done_cb;
2533 e->start_time = GNUNET_TIME_absolute_get();
2535 /* Start total time out */
2536 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2537 &timeout_experiment, e);
2540 if (NULL == e->start)
2547 fprintf (stderr, "Running episode %u with timeout %s\n",
2549 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2550 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2551 &timeout_episode, e);
2552 enforce_episode(e->cur);
2557 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2559 if (NULL != e->experiment_timeout_task)
2561 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2562 e->experiment_timeout_task = NULL;
2564 if (NULL != e->episode_timeout_task)
2566 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2567 e->episode_timeout_task = NULL;
2571 GNUNET_CONFIGURATION_destroy(e->cfg);
2574 free_experiment (e);
2579 GNUNET_ATS_solvers_experimentation_load (char *filename)
2581 struct Experiment *e;
2582 struct GNUNET_CONFIGURATION_Handle *cfg;
2585 cfg = GNUNET_CONFIGURATION_create();
2586 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2588 fprintf (stderr, "Failed to load `%s'\n", filename);
2589 GNUNET_CONFIGURATION_destroy (cfg);
2593 e = create_experiment ();
2595 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2598 fprintf (stderr, "Invalid %s \n", "name");
2599 free_experiment (e);
2603 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2605 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2606 "log_prefix", &e->log_prefix))
2608 fprintf (stderr, "Invalid %s \n", "log_prefix");
2609 free_experiment (e);
2613 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2616 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2617 "log_output_dir", &e->log_output_dir))
2619 e->log_output_dir = NULL;
2622 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging output directory: `%s'\n",
2626 if (GNUNET_SYSERR == (e->log_append_time_stamp = GNUNET_CONFIGURATION_get_value_yesno(cfg,
2627 "experiment", "log_append_time_stamp")))
2628 e->log_append_time_stamp = GNUNET_YES;
2629 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging append timestamp: `%s'\n",
2630 (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
2633 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2634 "cfg_file", &e->cfg_file))
2636 fprintf (stderr, "Invalid %s \n", "cfg_file");
2637 free_experiment (e);
2642 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n", e->cfg_file);
2643 e->cfg = GNUNET_CONFIGURATION_create();
2644 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2646 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2647 free_experiment (e);
2653 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2654 "log_freq", &e->log_freq))
2656 fprintf (stderr, "Invalid %s \n", "log_freq");
2657 free_experiment (e);
2661 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2662 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
2664 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2665 "max_duration", &e->max_duration))
2667 fprintf (stderr, "Invalid %s", "max_duration");
2668 free_experiment (e);
2672 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2673 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
2675 if (GNUNET_SYSERR == load_episodes (e, cfg))
2677 GNUNET_ATS_solvers_experimentation_stop (e);
2678 GNUNET_CONFIGURATION_destroy (cfg);
2680 fprintf (stderr, "Failed to load experiment\n");
2683 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded %u episodes with total duration %s\n",
2685 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
2687 GNUNET_CONFIGURATION_destroy (cfg);
2698 free_all_it (void *cls,
2699 const struct GNUNET_PeerIdentity *key,
2702 struct ATS_Address *address = value;
2703 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (sh->env.addresses,
2705 GNUNET_free (address);
2711 GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2713 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2715 GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
2717 GAS_normalization_stop();
2719 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
2722 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
2723 GNUNET_free (sh->plugin);
2729 * Load quotas for networks from configuration
2731 * @param cfg configuration handle
2732 * @param out_dest where to write outbound quotas
2733 * @param in_dest where to write inbound quotas
2734 * @param dest_length length of inbound and outbound arrays
2735 * @return number of networks loaded
2738 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2739 unsigned long long *out_dest,
2740 unsigned long long *in_dest,
2743 char * entry_in = NULL;
2744 char * entry_out = NULL;
2745 char * quota_out_str;
2746 char * quota_in_str;
2750 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
2754 GNUNET_asprintf (&entry_out,
2756 GNUNET_ATS_print_network_type (c));
2757 GNUNET_asprintf (&entry_in,
2759 GNUNET_ATS_print_network_type (c));
2762 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
2765 if (0 == strcmp(quota_out_str, BIG_M_STRING))
2767 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2770 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
2772 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
2775 if (GNUNET_NO == res)
2777 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2778 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2779 GNUNET_ATS_print_network_type (c),
2781 GNUNET_ATS_DefaultBandwidth);
2782 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2787 "Outbound quota configure for network `%s' is %llu\n",
2788 GNUNET_ATS_print_network_type (c),
2791 GNUNET_free (quota_out_str);
2795 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2796 _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
2797 GNUNET_ATS_print_network_type (c),
2798 GNUNET_ATS_DefaultBandwidth);
2799 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2803 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
2806 if (0 == strcmp(quota_in_str, BIG_M_STRING))
2808 in_dest[c] = GNUNET_ATS_MaxBandwidth;
2811 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
2813 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
2816 if (GNUNET_NO == res)
2818 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2819 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2820 GNUNET_ATS_print_network_type (c),
2822 GNUNET_ATS_DefaultBandwidth);
2823 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
2827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2828 "Inbound quota configured for network `%s' is %llu\n",
2829 GNUNET_ATS_print_network_type (c),
2832 GNUNET_free (quota_in_str);
2836 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2837 _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
2838 GNUNET_ATS_print_network_type (c),
2839 GNUNET_ATS_DefaultBandwidth);
2840 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2842 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2843 "Loaded quota for network `%s' (in/out): %llu %llu\n",
2844 GNUNET_ATS_print_network_type (c),
2847 GNUNET_free (entry_out);
2848 GNUNET_free (entry_in);
2850 return GNUNET_ATS_NetworkTypeCount;
2855 * Information callback for the solver
2857 * @param cls the closure
2858 * @param op the solver operation
2859 * @param stat status of the solver operation
2860 * @param add additional solver information
2863 solver_info_cb (void *cls,
2864 enum GAS_Solver_Operation op,
2865 enum GAS_Solver_Status stat,
2866 enum GAS_Solver_Additional_Information add)
2871 add_info = "GAS_INFO_NONE";
2874 add_info = "GAS_INFO_MLP_FULL";
2876 case GAS_INFO_UPDATED:
2877 add_info = "GAS_INFO_MLP_UPDATED";
2879 case GAS_INFO_PROP_ALL:
2880 add_info = "GAS_INFO_PROP_ALL";
2882 case GAS_INFO_PROP_SINGLE:
2883 add_info = "GAS_INFO_PROP_SINGLE";
2886 add_info = "INVALID";
2892 case GAS_OP_SOLVE_START:
2893 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2894 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
2895 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2897 case GAS_OP_SOLVE_STOP:
2898 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2899 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
2900 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2903 case GAS_OP_SOLVE_SETUP_START:
2904 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2905 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
2906 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2909 case GAS_OP_SOLVE_SETUP_STOP:
2910 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2911 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
2912 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2915 case GAS_OP_SOLVE_MLP_LP_START:
2916 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2917 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
2918 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2920 case GAS_OP_SOLVE_MLP_LP_STOP:
2921 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2922 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
2923 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2926 case GAS_OP_SOLVE_MLP_MLP_START:
2927 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2928 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
2929 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2931 case GAS_OP_SOLVE_MLP_MLP_STOP:
2932 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2933 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
2934 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2936 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
2937 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2938 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
2939 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2941 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
2942 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2943 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
2944 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2952 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
2954 struct GNUNET_TIME_Relative duration;
2956 static struct PreferenceGenerator *pg;
2958 if ( (0 == address->assigned_bw_out) && (0 == address->assigned_bw_in) )
2960 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2961 "Solver notified to disconnect peer `%s'\n",
2962 GNUNET_i2s (&address->peer));
2964 p = find_peer_by_pid(&address->peer);
2967 p->assigned_bw_out = address->assigned_bw_out;
2968 p->assigned_bw_in = address->assigned_bw_in;
2970 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
2972 if (pg->peer == p->id)
2974 duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
2975 delta = duration.rel_value_us * pg->last_assigned_bw_out;
2976 pg->feedback_bw_out_acc += delta;
2978 delta = duration.rel_value_us * pg->last_assigned_bw_in;
2979 pg->feedback_bw_in_acc += delta;
2981 pg->last_assigned_bw_in = address->assigned_bw_in;
2982 pg->last_assigned_bw_out = address->assigned_bw_out;
2983 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
2987 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2988 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
2989 GNUNET_i2s (&address->peer),
2991 address->assigned_bw_out,
2992 address->assigned_bw_in);
2995 GNUNET_ATS_solver_logging_now (l);
3001 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3004 if (GNUNET_YES == opt_disable_normalization)
3006 if (NULL == (p = find_peer_by_pid (id)))
3011 return GAS_preference_get_by_peer (NULL,
3016 struct SolverHandle *
3017 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3019 struct SolverHandle *sh;
3023 case GNUNET_ATS_SOLVER_PROPORTIONAL:
3024 solver_str = "proportional";
3026 case GNUNET_ATS_SOLVER_MLP:
3029 case GNUNET_ATS_SOLVER_RIL:
3038 sh = GNUNET_new (struct SolverHandle);
3039 GNUNET_asprintf (&sh->plugin,
3040 "libgnunet_plugin_ats_%s",
3042 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
3044 /* setup environment */
3045 sh->env.cfg = e->cfg;
3046 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
3047 sh->env.addresses = sh->addresses;
3048 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
3049 sh->env.get_preferences = &get_preferences_cb;
3050 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
3051 sh->env.info_cb = &solver_info_cb;
3052 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
3054 /* start normalization */
3055 GAS_normalization_start ();
3058 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
3059 sh->env.out_quota, sh->env.in_quota, GNUNET_ATS_NetworkTypeCount))
3062 GNUNET_free (sh->plugin);
3068 sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
3071 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
3073 GNUNET_free (sh->plugin);
3085 struct TestPeer *cur;
3086 struct TestPeer *next;
3088 struct TestAddress *cur_a;
3089 struct TestAddress *next_a;
3092 GNUNET_ATS_solver_logging_stop (l);
3094 /* Stop all preference generation */
3095 GNUNET_ATS_solver_generate_preferences_stop_all ();
3097 /* Stop all property generation */
3098 GNUNET_ATS_solver_generate_property_stop_all ();
3102 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
3103 GNUNET_ATS_solver_logging_eval (l);
3107 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
3108 GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
3114 GNUNET_ATS_solver_logging_free (l);
3118 /* Clean up experiment */
3121 GNUNET_ATS_solvers_experimentation_stop (e);
3126 while (NULL != (cur = next))
3129 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3130 next_a = cur->addr_head;
3131 while (NULL != (cur_a = next_a))
3133 next_a = cur_a->next;
3134 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3135 GNUNET_free (cur_a);
3141 GNUNET_ATS_solvers_solver_stop (sh);
3150 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
3152 if (GNUNET_OK == success)
3153 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3154 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3156 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3158 GNUNET_SCHEDULER_add_now (&done, NULL);
3162 episode_done_cb (struct Episode *ep)
3164 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3177 GNUNET_ATS_solvers_experimentation_stop (e);
3182 GNUNET_ATS_solvers_solver_stop (sh);
3188 run (void *cls, char * const *args, const char *cfgfile,
3189 const struct GNUNET_CONFIGURATION_Handle *cfg)
3191 enum GNUNET_ATS_Solvers solver;
3194 if (NULL == opt_exp_file)
3196 fprintf (stderr, "No experiment given ...\n");
3202 if (NULL == opt_solver)
3204 fprintf (stderr, "No solver given ...\n");
3210 if (0 == strcmp(opt_solver, "mlp"))
3212 solver = GNUNET_ATS_SOLVER_MLP;
3214 else if (0 == strcmp(opt_solver, "proportional"))
3216 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3218 else if (0 == strcmp(opt_solver, "ril"))
3220 solver = GNUNET_ATS_SOLVER_RIL;
3224 fprintf (stderr, "No solver given ...");
3230 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3231 default_properties[c] = DEFAULT_REL_QUALITY;
3233 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3234 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3236 /* load experiment */
3237 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3238 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3241 fprintf (stderr, "Failed to load experiment ...\n");
3248 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3249 sh = GNUNET_ATS_solvers_solver_start (solver);
3252 fprintf (stderr, "Failed to start solver ...\n");
3259 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3260 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3262 /* run experiment */
3263 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3264 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3265 experiment_done_cb);
3272 * Main function of the benchmark
3274 * @param argc argument count
3275 * @param argv argument values
3278 main (int argc, char *argv[])
3280 opt_exp_file = NULL;
3282 opt_log = GNUNET_NO;
3283 opt_save = GNUNET_NO;
3287 static struct GNUNET_GETOPT_CommandLineOption options[] =
3289 { 's', "solver", NULL,
3290 gettext_noop ("solver to use"),
3291 1, &GNUNET_GETOPT_set_string, &opt_solver},
3292 { 'e', "experiment", NULL,
3293 gettext_noop ("experiment to use"),
3294 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
3295 { 'V', "verbose", NULL,
3296 gettext_noop ("be verbose"),
3297 0, &GNUNET_GETOPT_set_one, &opt_verbose},
3298 { 'p', "print", NULL,
3299 gettext_noop ("print logging"),
3300 0, &GNUNET_GETOPT_set_one, &opt_print},
3301 { 'f', "file", NULL,
3302 gettext_noop ("save logging to disk"),
3303 0, &GNUNET_GETOPT_set_one, &opt_save},
3305 gettext_noop ("disable normalization"),
3306 0, &GNUNET_GETOPT_set_one, &opt_disable_normalization},
3307 GNUNET_GETOPT_OPTION_END
3310 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3311 NULL, options, &run, argv[0]);
3315 /* end of file ats-testing-experiment.c*/