2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, 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, "Logging peer id %llu\n", cur->id);
171 log_p = GNUNET_new (struct LoggingPeer);
173 log_p->peer_id = cur->peer_id;
174 log_p->is_requested = cur->is_requested;
175 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
177 log_p->pref_abs[c] = cur->pref_abs[c];
178 log_p->pref_norm[c] = cur->pref_norm[c];
179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n",
180 GNUNET_ATS_print_preference_type(c),
181 log_p->pref_abs[c], log_p->pref_norm[c]);
183 GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p);
185 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
187 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %llu address %llu \n",
188 cur->id, cur_addr->aid);
189 log_a = GNUNET_new (struct LoggingAddress);
190 log_a->aid = cur_addr->aid;
191 log_a->active = cur_addr->ats_addr->active;
192 log_a->network = cur_addr->network;
193 log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
194 log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
195 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
197 log_a->prop_abs[c] = cur_addr->prop_abs[c];
198 log_a->prop_norm[c] = cur_addr->prop_norm[c];
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n",
200 GNUNET_ATS_print_property_type(c),
201 log_a->prop_abs[c], log_a->prop_norm[c]);
203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in);
205 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "\t BW out = %llu\n", log_a->assigned_bw_out);
207 GNUNET_CONTAINER_DLL_insert_tail (log_p->addr_head, log_p->addr_tail, log_a);
213 logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
215 struct LoggingHandle *l = cls;
216 l->logging_task = NULL;
218 GNUNET_ATS_solver_logging_now (l);
220 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq, &logging_task, l);
224 struct LoggingHandle *
225 GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
227 struct LoggingHandle *l;
228 l = GNUNET_new (struct LoggingHandle);
230 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
231 GNUNET_STRINGS_relative_time_to_string(freq, GNUNET_NO));
233 l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
238 GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
240 if (NULL != l->logging_task)
241 GNUNET_SCHEDULER_cancel (l->logging_task);
243 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
245 l->logging_task = NULL;
248 static struct LoggingFileHandle *
249 find_logging_file_handle (struct LoggingFileHandle *lf_head,
250 struct LoggingFileHandle *lf_tail,
251 int peer_id, int address_id)
253 struct LoggingFileHandle *res;
255 for (res = lf_head; NULL != res; res = res->next)
256 if ((res->pid == peer_id) && (res->aid == address_id))
263 GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int add_time_stamp,
266 struct LoggingTimeStep *lts;
267 struct LoggingPeer *log_p;
268 struct LoggingAddress *log_a;
269 struct LoggingFileHandle *lf_head;
270 struct LoggingFileHandle *lf_tail;
271 struct LoggingFileHandle *cur;
272 struct LoggingFileHandle *next;
276 char * propstring_tmp;
278 char * prefstring_tmp;
283 if (NULL != output_dir)
285 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (output_dir))
287 fprintf (stderr, "Failed to create directory `%s'\n", output_dir);
292 fprintf (stderr, "Created directory `%s'\n", output_dir);
293 use_dir = GNUNET_YES;
300 for (lts = l->head; NULL != lts; lts = lts->next)
303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing log step %llu\n",
304 (long long unsigned int) lts->timestamp.abs_value_us);
306 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
308 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
311 cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
315 cur = GNUNET_new (struct LoggingFileHandle);
316 cur->aid = log_a->aid;
317 cur->pid = log_p->id;
319 if (GNUNET_YES == add_time_stamp)
320 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u_%llu.log",
321 (GNUNET_YES == use_dir) ? output_dir : "",
322 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
327 l->head->timestamp.abs_value_us);
329 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u.log",
330 (GNUNET_YES == use_dir) ? output_dir : "",
331 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
337 fprintf (stderr, "Add writing log data for peer %llu address %llu to file `%s'\n",
338 cur->pid, cur->aid, filename);
341 cur->f_hd = GNUNET_DISK_file_open (filename,
342 GNUNET_DISK_OPEN_READWRITE |
343 GNUNET_DISK_OPEN_CREATE |
344 GNUNET_DISK_OPEN_TRUNCATE,
345 GNUNET_DISK_PERM_USER_READ |
346 GNUNET_DISK_PERM_USER_WRITE |
347 GNUNET_DISK_PERM_GROUP_READ |
348 GNUNET_DISK_PERM_OTHER_READ);
349 if (NULL == cur->f_hd)
351 fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
352 GNUNET_free (filename);
356 GNUNET_free (filename);
357 GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
359 GNUNET_asprintf(&datastring,"#time delta;log duration;peer_requested;addr net; addr_active; bw in; bw out; " \
360 "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
361 "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;"\
363 "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
364 "COST_WLAN; COST_WLAN;COST_BT; COST_BT; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n");
365 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
366 GNUNET_free (datastring);
370 prefstring = GNUNET_strdup("");
371 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
374 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
375 GNUNET_ATS_print_preference_type(c),
376 log_p->pref_abs[c], log_p->pref_norm[c]);
378 GNUNET_asprintf(&prefstring_tmp,"%s;%.3f;%.3f",
379 prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
382 GNUNET_free (prefstring);
383 prefstring = GNUNET_strdup(prefstring_tmp);
384 GNUNET_free (prefstring_tmp);
388 propstring = GNUNET_strdup("");
389 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
391 if (GNUNET_ATS_NETWORK_TYPE == c)
394 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
395 GNUNET_ATS_print_property_type(c),
396 log_a->prop_abs[c], log_a->prop_norm[c]);*/
397 GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;",
398 propstring, log_a->prop_abs[c], log_a->prop_norm[c]);
399 GNUNET_free (propstring);
400 propstring = GNUNET_strdup(propstring_tmp);
401 GNUNET_free (propstring_tmp);
403 GNUNET_asprintf (&datastring, "%llu;%llu;%u;%u;%i;%u;%u;%s;%s\n",
404 GNUNET_TIME_absolute_get_difference (l->head->timestamp,
405 lts->timestamp).rel_value_us / 1000, lts->delta,
406 log_p->is_requested, log_a->network, log_a->active,
407 log_a->assigned_bw_in, log_a->assigned_bw_out, propstring,
410 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
411 GNUNET_free (datastring);
412 GNUNET_free (prefstring);
413 GNUNET_free (propstring);
420 for (cur = next; NULL != cur; cur = next)
423 GNUNET_CONTAINER_DLL_remove (lf_head, lf_tail, cur);
424 if (NULL != cur->f_hd)
425 GNUNET_DISK_file_close (cur->f_hd);
432 GNUNET_ATS_solver_logging_eval (struct LoggingHandle *l)
434 struct LoggingTimeStep *lts;
435 struct LoggingPeer *log_p;
436 struct LoggingAddress *log_a;
439 for (lts = l->head; NULL != lts; lts = lts->next)
441 fprintf (stderr, "Log step %llu %llu: \n",
442 (long long unsigned int) lts->timestamp.abs_value_us,
443 (long long unsigned int) lts->delta.rel_value_us);
445 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
447 fprintf (stderr,"\tLogging peer pid %llu\n", log_p->id);
448 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
450 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
451 GNUNET_ATS_print_preference_type(c),
452 log_p->pref_abs[c], log_p->pref_norm[c]);
455 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
457 fprintf (stderr, "\tPeer pid %llu address %llu: %u %u %u\n",
458 log_p->id, log_a->aid, log_a->active,
459 log_a->assigned_bw_in,
460 log_a->assigned_bw_out);
462 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
464 if (GNUNET_ATS_NETWORK_TYPE == c)
466 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
467 GNUNET_ATS_print_property_type(c),
468 log_a->prop_abs[c], log_a->prop_norm[c]);
476 GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
478 struct LoggingTimeStep *lts_cur;
479 struct LoggingTimeStep *lts_next;
480 struct LoggingPeer *log_p_cur;
481 struct LoggingPeer *log_p_next;
482 struct LoggingAddress *log_a_cur;
483 struct LoggingAddress *log_a_next;
485 if (NULL != l->logging_task)
486 GNUNET_SCHEDULER_cancel (l->logging_task);
487 l->logging_task = NULL;
490 while (NULL != (lts_cur = lts_next))
492 lts_next = lts_cur->next;
494 log_p_next = lts_cur->head;
495 while (NULL != (log_p_cur = log_p_next))
497 log_p_next = log_p_cur->next;
499 log_a_next = log_p_cur->addr_head;
500 while (NULL != (log_a_cur = log_a_next))
502 log_a_next = log_a_cur->next;
504 GNUNET_CONTAINER_DLL_remove (log_p_cur->addr_head, log_p_cur->addr_tail, log_a_cur);
505 GNUNET_free (log_a_cur);
508 GNUNET_CONTAINER_DLL_remove (lts_cur->head, lts_cur->tail, log_p_cur);
509 GNUNET_free (log_p_cur);
512 GNUNET_CONTAINER_DLL_remove (l->head, l->tail, lts_cur);
513 GNUNET_free (lts_cur);
520 * Property Generators
523 static struct PropertyGenerator *prop_gen_head;
524 static struct PropertyGenerator *prop_gen_tail;
527 get_property (struct PropertyGenerator *pg)
529 struct GNUNET_TIME_Relative time_delta;
533 /* Calculate the current preference value */
535 case GNUNET_ATS_TEST_TG_CONSTANT:
536 pref_value = pg->base_value;
538 case GNUNET_ATS_TEST_TG_LINEAR:
539 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
540 /* Calculate point of time in the current period */
541 time_delta.rel_value_us = time_delta.rel_value_us %
542 pg->duration_period.rel_value_us;
543 delta_value = ((double) time_delta.rel_value_us /
544 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
545 if ((pg->max_value < pg->base_value) &&
546 ((pg->max_value - pg->base_value) > pg->base_value))
548 /* This will cause an underflow */
551 pref_value = pg->base_value + delta_value;
553 case GNUNET_ATS_TEST_TG_RANDOM:
554 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
555 10000 * (pg->max_value - pg->base_value)) / 10000;
556 pref_value = pg->base_value + delta_value;
558 case GNUNET_ATS_TEST_TG_SINUS:
559 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
560 /* Calculate point of time in the current period */
561 time_delta.rel_value_us = time_delta.rel_value_us %
562 pg->duration_period.rel_value_us;
563 if ((pg->max_value - pg->base_value) > pg->base_value)
565 /* This will cause an underflow for second half of sinus period,
566 * will be detected in general when experiments are loaded */
569 delta_value = (pg->max_value - pg->base_value) *
570 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
571 time_delta.rel_value_us);
572 pref_value = pg->base_value + delta_value;
578 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current property value is %f\n",
585 set_prop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
587 struct PropertyGenerator *pg = cls;
589 struct TestAddress *a;
591 struct GNUNET_ATS_Information atsi;
595 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains_value (sh->addresses,
596 &pg->test_peer->peer_id, pg->test_address->ats_addr))
599 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
600 "Setting property generation for unknown address [%u:%u]\n",
601 pg->peer, pg->address_id);
604 if (NULL == (p = find_peer_by_id (pg->peer)))
607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
608 "Setting property generation for unknown peer %u\n",
612 if (NULL == (a = find_address_by_id (p, pg->address_id)))
615 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
616 "Setting property generation for unknown peer %u\n",
621 prop_value = get_property (pg);
622 a->prop_abs[pg->ats_property] = prop_value;
624 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
625 "Setting property for peer [%u] address [%u] for %s to %f\n",
626 pg->peer, pg->address_id,
627 GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
629 atsi.type = htonl (pg->ats_property);
630 atsi.value = htonl ((uint32_t) prop_value);
632 /* set performance here! */
633 sh->sf->s_bulk_start (sh->sf->cls);
634 if (GNUNET_YES == opt_disable_normalization)
636 a->prop_abs[pg->ats_property] = prop_value;
637 a->prop_norm[pg->ats_property] = prop_value;
638 sh->sf->s_address_update_property (sh->sf->cls, a->ats_addr,
639 pg->ats_property, prop_value, prop_value);
642 GAS_normalization_update_property (pg->test_address->ats_addr, &atsi, 1);
643 sh->sf->s_bulk_stop (sh->sf->cls);
645 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
651 * Set ats_property to 0 to find all pgs
653 static struct PropertyGenerator *
654 find_prop_gen (unsigned int peer, unsigned int address,
655 uint32_t ats_property)
657 struct PropertyGenerator *cur;
658 for (cur = prop_gen_head; NULL != cur; cur = cur->next)
659 if ((cur->peer == peer) && (cur->address_id == address))
661 if ((cur->ats_property == ats_property) || (0 == ats_property))
668 GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
670 GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
672 if (NULL != pg->set_task)
674 GNUNET_SCHEDULER_cancel (pg->set_task);
677 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
678 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
679 pg->peer, pg->address_id,
680 GNUNET_ATS_print_property_type(pg->ats_property));
687 * Generate between the source master and the partner and set property with a
688 * value depending on the generator.
691 * @param address_id partner
692 * @param test_peer the peer
693 * @param test_address the address
694 * @param type type of generator
695 * @param base_value base value
696 * @param value_rate maximum value
697 * @param period duration of a period of generation (~ 1/frequency)
698 * @param frequency how long to generate property
699 * @param ats_property ATS property to generate
700 * @return the property generator
702 struct PropertyGenerator *
703 GNUNET_ATS_solver_generate_property_start (unsigned int peer,
704 unsigned int address_id,
705 struct TestPeer *test_peer,
706 struct TestAddress *test_address,
707 enum GeneratorType type,
710 struct GNUNET_TIME_Relative period,
711 struct GNUNET_TIME_Relative frequency,
712 uint32_t ats_property)
714 struct PropertyGenerator *pg;
716 pg = GNUNET_new (struct PropertyGenerator);
717 GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
720 pg->test_address = test_address;
721 pg->test_peer = test_peer;
722 pg->address_id = address_id;
723 pg->ats_property = ats_property;
724 pg->base_value = base_value;
725 pg->max_value = value_rate;
726 pg->duration_period = period;
727 pg->frequency = frequency;
728 pg->time_start = GNUNET_TIME_absolute_get();
731 case GNUNET_ATS_TEST_TG_CONSTANT:
732 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
733 "Setting up %s property generator peer [%u] address [%u] `%s'"\
735 print_generator_type(type), pg->peer, pg->address_id,
736 GNUNET_ATS_print_property_type (ats_property),
739 case GNUNET_ATS_TEST_TG_LINEAR:
740 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
741 "Setting up %s property generator peer [%u] address [%u] `%s' " \
742 "min %u Bips max %u Bips\n",
743 print_generator_type(type), pg->peer, pg->address_id,
744 GNUNET_ATS_print_property_type(ats_property),
745 base_value, value_rate);
747 case GNUNET_ATS_TEST_TG_SINUS:
748 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
749 "Setting up %s property generator peer [%u] address [%u] `%s' "\
750 "baserate %u Bips, amplitude %u Bps\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_RANDOM:
756 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
757 "Setting up %s property generator peer [%u] address [%u] `%s' "\
758 "min %u Bips max %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);
767 pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
773 * Stop all preferences generators
776 GNUNET_ATS_solver_generate_property_stop_all ()
778 struct PropertyGenerator *cur;
779 struct PropertyGenerator *next;
780 next = prop_gen_head;
781 for (cur = next; NULL != cur; cur = next)
784 GNUNET_ATS_solver_generate_property_stop (cur);
790 * Preference Generators
792 static struct PreferenceGenerator *pref_gen_head;
793 static struct PreferenceGenerator *pref_gen_tail;
797 get_preference (struct PreferenceGenerator *pg)
799 struct GNUNET_TIME_Relative time_delta;
803 /* Calculate the current preference value */
805 case GNUNET_ATS_TEST_TG_CONSTANT:
806 pref_value = pg->base_value;
808 case GNUNET_ATS_TEST_TG_LINEAR:
809 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
810 /* Calculate point of time in the current period */
811 time_delta.rel_value_us = time_delta.rel_value_us %
812 pg->duration_period.rel_value_us;
813 delta_value = ((double) time_delta.rel_value_us /
814 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
815 if ((pg->max_value < pg->base_value) &&
816 ((pg->max_value - pg->base_value) > pg->base_value))
818 /* This will cause an underflow */
821 pref_value = pg->base_value + delta_value;
823 case GNUNET_ATS_TEST_TG_RANDOM:
824 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
825 10000 * (pg->max_value - pg->base_value)) / 10000;
826 pref_value = pg->base_value + delta_value;
828 case GNUNET_ATS_TEST_TG_SINUS:
829 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
830 /* Calculate point of time in the current period */
831 time_delta.rel_value_us = time_delta.rel_value_us %
832 pg->duration_period.rel_value_us;
833 if ((pg->max_value - pg->base_value) > pg->base_value)
835 /* This will cause an underflow for second half of sinus period,
836 * will be detected in general when experiments are loaded */
839 delta_value = (pg->max_value - pg->base_value) *
840 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
841 time_delta.rel_value_us);
842 pref_value = pg->base_value + delta_value;
848 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
854 set_feedback_task (void *cls,
855 const struct GNUNET_SCHEDULER_TaskContext *tc)
857 struct PreferenceGenerator *pg = cls;
862 uint32_t delay_acc_in;
863 struct GNUNET_TIME_Relative dur;
866 pg->feedback_task = NULL;
868 if (NULL == (p = find_peer_by_id (pg->peer)))
871 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
872 "Setting feedback for unknown peer %u\n", pg->peer);
878 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
879 dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
880 bw_acc_in = dur.rel_value_us *pg->last_assigned_bw_in + pg->feedback_bw_in_acc;
881 pg->feedback_bw_in_acc = 0;
883 bw_acc_out = dur.rel_value_us *pg->last_assigned_bw_out + pg->feedback_bw_out_acc;
884 p_new = get_preference (pg);
885 feedback = (p_new / pg->pref_bw_old) * (bw_acc_in + bw_acc_out) /
886 (2 *GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
889 case GNUNET_ATS_PREFERENCE_LATENCY:
890 dur = GNUNET_TIME_absolute_get_duration(pg->feedback_last_delay_update);
891 delay_acc_in =dur.rel_value_us *pg->last_delay_value + pg->feedback_delay_acc;
892 pg->feedback_delay_acc = 0;
894 p_new = get_preference (pg);
895 feedback = (p_new / pg->pref_latency_old) * (delay_acc_in) /
896 (GNUNET_TIME_absolute_get_duration(pg->feedback_last).rel_value_us);
904 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
905 "Giving feedback for peer [%u] for client %p pref %s of %.3f\n",
906 pg->peer, NULL + (pg->client_id),
907 GNUNET_ATS_print_preference_type (pg->kind),
910 sh->sf->s_feedback (sh->sf->cls, NULL + (pg->client_id), &p->peer_id,
911 pg->feedback_frequency, pg->kind, feedback);
912 pg->feedback_last = GNUNET_TIME_absolute_get();
915 pg->feedback_bw_out_acc = 0;
916 pg->feedback_bw_in_acc = 0;
917 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
919 pg->feedback_delay_acc = 0;
920 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
923 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (pg->feedback_frequency,
924 &set_feedback_task, pg);
929 set_pref_task (void *cls,
930 const struct GNUNET_SCHEDULER_TaskContext *tc)
932 struct PreferenceGenerator *pg = cls;
937 if (NULL == (p = find_peer_by_id (pg->peer)))
940 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
941 "Setting preference for unknown peer %u\n", pg->peer);
945 pref_value = get_preference (pg);
947 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
948 pg->pref_bw_old = pref_value;
950 case GNUNET_ATS_PREFERENCE_LATENCY:
951 pg->pref_latency_old = pref_value;
957 p->pref_abs[pg->kind] = pref_value;
959 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
960 "Setting preference for peer [%u] for client %p pref %s to %f\n",
961 pg->peer, NULL + (pg->client_id),
962 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
964 if (GNUNET_YES == opt_disable_normalization)
966 p->pref_abs[pg->kind] = pref_value;
967 p->pref_norm[pg->kind] = pref_value;
968 sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
971 normalize_preference (NULL + (pg->client_id),
976 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
982 static struct PreferenceGenerator *
983 find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
985 struct PreferenceGenerator *cur;
986 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
987 if (cur->peer == peer)
989 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
996 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
998 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
1000 if (NULL != pg->feedback_task)
1002 GNUNET_SCHEDULER_cancel (pg->feedback_task);
1003 pg->feedback_task = NULL;
1006 if (NULL != pg->set_task)
1008 GNUNET_SCHEDULER_cancel (pg->set_task);
1009 pg->set_task = NULL;
1011 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1012 "Removing old up preference generator peer [%u] `%s'\n",
1013 pg->peer, GNUNET_ATS_print_preference_type(pg->kind));
1019 static struct TestAddress*
1020 find_active_address (struct TestPeer *p)
1022 struct TestAddress *cur;
1023 for (cur = p->addr_head; NULL != cur; cur = cur->next)
1024 if (GNUNET_YES == cur->ats_addr->active)
1031 * Generate between the source master and the partner and set property with a
1032 * value depending on the generator.
1034 * @param peer source
1035 * @param address_id partner
1036 * @param client_id the client
1037 * @param type type of generator
1038 * @param base_value base value
1039 * @param value_rate maximum value
1040 * @param period duration of a period of generation (~ 1/frequency)
1041 * @param frequency how long to generate property
1042 * @param kind ATS preference to generate
1043 * @param feedback_frequency how often to give feedback
1044 * @return the preference generator
1046 struct PreferenceGenerator *
1047 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
1048 unsigned int address_id,
1049 unsigned int client_id,
1050 enum GeneratorType type,
1051 long int base_value,
1052 long int value_rate,
1053 struct GNUNET_TIME_Relative period,
1054 struct GNUNET_TIME_Relative frequency,
1055 enum GNUNET_ATS_PreferenceKind kind,
1056 struct GNUNET_TIME_Relative feedback_frequency)
1058 struct PreferenceGenerator *pg;
1061 if (NULL == (p = find_peer_by_id (peer)))
1064 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1065 "Starting preference for unknown peer %u\n", peer);
1069 pg = GNUNET_new (struct PreferenceGenerator);
1070 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
1073 pg->client_id = client_id;
1075 pg->base_value = base_value;
1076 pg->max_value = value_rate;
1077 pg->duration_period = period;
1078 pg->frequency = frequency;
1079 pg->time_start = GNUNET_TIME_absolute_get();
1080 pg->feedback_frequency = feedback_frequency;
1083 case GNUNET_ATS_TEST_TG_CONSTANT:
1084 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1085 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
1086 print_generator_type (type), pg->peer,
1087 GNUNET_ATS_print_preference_type(kind),
1090 case GNUNET_ATS_TEST_TG_LINEAR:
1091 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1092 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
1093 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1094 base_value, value_rate);
1096 case GNUNET_ATS_TEST_TG_SINUS:
1097 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1098 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
1099 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1100 base_value, value_rate);
1102 case GNUNET_ATS_TEST_TG_RANDOM:
1103 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1104 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1105 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1106 base_value, value_rate);
1112 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1113 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != feedback_frequency.rel_value_us)
1115 struct TestAddress * addr = find_active_address(p);
1117 pg->last_assigned_bw_in = p->assigned_bw_in;
1118 pg->last_assigned_bw_out = p->assigned_bw_out;
1119 pg->feedback_bw_in_acc = 0;
1120 pg->feedback_bw_out_acc = 0;
1121 pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
1122 pg->feedback_delay_acc = 0;
1124 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
1125 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
1126 pg->feedback_last = GNUNET_TIME_absolute_get();
1127 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
1128 &set_feedback_task, pg);
1137 * Stop all preferences generators
1140 GNUNET_ATS_solver_generate_preferences_stop_all ()
1142 struct PreferenceGenerator *cur;
1143 struct PreferenceGenerator *next;
1144 next = pref_gen_head;
1145 for (cur = next; NULL != cur; cur = next)
1148 GNUNET_ATS_solver_generate_preferences_stop(cur);
1158 print_op (enum OperationType op)
1161 case SOLVER_OP_ADD_ADDRESS:
1162 return "ADD_ADDRESS";
1163 case SOLVER_OP_DEL_ADDRESS:
1164 return "DEL_ADDRESS";
1165 case SOLVER_OP_START_SET_PREFERENCE:
1166 return "START_SET_PREFERENCE";
1167 case SOLVER_OP_STOP_SET_PREFERENCE:
1168 return "STOP_STOP_PREFERENCE";
1169 case SOLVER_OP_START_SET_PROPERTY:
1170 return "START_SET_PROPERTY";
1171 case SOLVER_OP_STOP_SET_PROPERTY:
1172 return "STOP_SET_PROPERTY";
1173 case SOLVER_OP_START_REQUEST:
1174 return "START_REQUEST";
1175 case SOLVER_OP_STOP_REQUEST:
1176 return "STOP_REQUEST";
1184 static struct Experiment *
1185 create_experiment ()
1187 struct Experiment *e;
1188 e = GNUNET_new (struct Experiment);
1191 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1197 free_experiment (struct Experiment *e)
1199 struct Episode *cur;
1200 struct Episode *next;
1201 struct GNUNET_ATS_TEST_Operation *cur_o;
1202 struct GNUNET_ATS_TEST_Operation *next_o;
1205 for (cur = next; NULL != cur; cur = next)
1210 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1212 next_o = cur_o->next;
1213 GNUNET_free_non_null (cur_o->address);
1214 GNUNET_free_non_null (cur_o->plugin);
1215 GNUNET_free (cur_o);
1220 GNUNET_free_non_null (e->name);
1221 GNUNET_free_non_null (e->log_prefix);
1222 GNUNET_free_non_null (e->log_output_dir);
1223 GNUNET_free_non_null (e->cfg_file);
1229 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1233 const struct GNUNET_CONFIGURATION_Handle *cfg)
1239 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1240 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1241 sec_name, op_name, &o->peer_id))
1243 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1244 op_counter, "ADD_ADDRESS", op_name);
1245 GNUNET_free (op_name);
1246 return GNUNET_SYSERR;
1248 GNUNET_free (op_name);
1251 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1252 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1253 sec_name, op_name, &o->address_id))
1255 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1256 op_counter, "ADD_ADDRESS", op_name);
1257 GNUNET_free (op_name);
1258 return GNUNET_SYSERR;
1260 GNUNET_free (op_name);
1263 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1264 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1265 sec_name, op_name, &o->plugin))
1267 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1268 op_counter, "ADD_ADDRESS", op_name);
1269 GNUNET_free (op_name);
1270 return GNUNET_SYSERR;
1272 GNUNET_free (op_name);
1275 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1276 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1277 sec_name, op_name, &o->address))
1279 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1280 op_counter, "ADD_ADDRESS", op_name);
1281 GNUNET_free (op_name);
1282 return GNUNET_SYSERR;
1284 GNUNET_free (op_name);
1287 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1288 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1289 sec_name, op_name, &o->address_session))
1291 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1292 op_counter, "ADD_ADDRESS", op_name);
1293 GNUNET_free (op_name);
1294 return GNUNET_SYSERR;
1296 GNUNET_free (op_name);
1299 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
1300 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1301 sec_name, op_name, &op_network))
1303 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
1304 op_counter, "ADD_ADDRESS", op_name);
1305 GNUNET_free (op_name);
1306 return GNUNET_SYSERR;
1310 GNUNET_STRINGS_utf8_toupper (op_network,op_network);
1311 if (0 == strcmp(op_network, "UNSPECIFIED"))
1313 o->address_network = GNUNET_ATS_NET_UNSPECIFIED;
1315 else if (0 == strcmp(op_network, "LOOPBACK"))
1317 o->address_network = GNUNET_ATS_NET_LOOPBACK;
1319 else if (0 == strcmp(op_network, "LAN"))
1321 o->address_network = GNUNET_ATS_NET_LAN;
1323 else if (0 == strcmp(op_network, "WAN"))
1325 o->address_network = GNUNET_ATS_NET_WAN;
1327 else if (0 == strcmp(op_network, "WLAN"))
1329 o->address_network = GNUNET_ATS_NET_WLAN;
1331 else if (0 == strcmp(op_network, "BT"))
1333 o->address_network = GNUNET_ATS_NET_BT;
1337 fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1338 op_counter, "ADD_ADDRESS", op_name, op_network);
1339 GNUNET_free (op_network);
1340 GNUNET_free (op_name);
1341 return GNUNET_SYSERR;
1344 GNUNET_free (op_network);
1345 GNUNET_free (op_name);
1347 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1348 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1349 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1356 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1360 const struct GNUNET_CONFIGURATION_Handle *cfg)
1366 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1367 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1368 sec_name, op_name, &o->peer_id))
1370 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1371 op_counter, "DEL_ADDRESS", op_name);
1372 GNUNET_free (op_name);
1373 return GNUNET_SYSERR;
1375 GNUNET_free (op_name);
1378 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1379 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1380 sec_name, op_name, &o->address_id))
1382 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1383 op_counter, "DEL_ADDRESS", op_name);
1384 GNUNET_free (op_name);
1385 return GNUNET_SYSERR;
1387 GNUNET_free (op_name);
1391 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1392 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1393 sec_name, op_name, &o->plugin))
1395 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1396 op_counter, "DEL_ADDRESS", op_name);
1397 GNUNET_free (op_name);
1398 return GNUNET_SYSERR;
1400 GNUNET_free (op_name);
1403 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1404 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1405 sec_name, op_name, &o->address))
1407 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1408 op_counter, "DEL_ADDRESS", op_name);
1409 GNUNET_free (op_name);
1410 return GNUNET_SYSERR;
1412 GNUNET_free (op_name);
1415 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1416 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1417 sec_name, op_name, &o->address_session))
1419 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1420 op_counter, "DEL_ADDRESS", op_name);
1421 GNUNET_free (op_name);
1422 return GNUNET_SYSERR;
1424 GNUNET_free (op_name);
1427 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1428 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1429 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1435 static enum GNUNET_ATS_Property
1436 parse_preference_string (const char * str)
1439 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1441 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1442 if (0 == strcmp(str, props[c]))
1449 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1453 const struct GNUNET_CONFIGURATION_Handle *cfg)
1460 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1461 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1462 sec_name, op_name, &o->peer_id))
1464 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1465 op_counter, "START_SET_PREFERENCE", op_name);
1466 GNUNET_free (op_name);
1467 return GNUNET_SYSERR;
1469 GNUNET_free (op_name);
1472 GNUNET_asprintf(&op_name, "op-%u-client-id", op_counter);
1473 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1474 sec_name, op_name, &o->client_id))
1476 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1477 op_counter, "START_SET_PREFERENCE", op_name);
1478 GNUNET_free (op_name);
1479 return GNUNET_SYSERR;
1481 GNUNET_free (op_name);
1484 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1485 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1486 sec_name, op_name, &type)) )
1488 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1489 op_counter, "START_SET_PREFERENCE", op_name);
1490 GNUNET_free (op_name);
1491 return GNUNET_SYSERR;
1494 /* Load arguments for set_rate, start_send, set_preference */
1495 if (0 == strcmp (type, "constant"))
1497 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1499 else if (0 == strcmp (type, "linear"))
1501 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1503 else if (0 == strcmp (type, "sinus"))
1505 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1507 else if (0 == strcmp (type, "random"))
1509 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1513 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1514 op_counter, op_name, e->id);
1516 GNUNET_free (op_name);
1517 return GNUNET_SYSERR;
1520 GNUNET_free (op_name);
1524 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1525 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1526 sec_name, op_name, &o->base_rate))
1528 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1529 op_counter, op_name, e->id);
1530 GNUNET_free (op_name);
1531 return GNUNET_SYSERR;
1533 GNUNET_free (op_name);
1537 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1538 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1539 sec_name, op_name, &o->max_rate))
1541 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1542 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1543 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1545 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1546 op_counter, op_name, e->id);
1547 GNUNET_free (op_name);
1548 return GNUNET_SYSERR;
1551 GNUNET_free (op_name);
1554 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1555 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1556 sec_name, op_name, &o->period))
1558 o->period = e->duration;
1560 GNUNET_free (op_name);
1563 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1564 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1565 sec_name, op_name, &o->frequency))
1567 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1568 op_counter, op_name, e->id);
1569 GNUNET_free (op_name);
1570 return GNUNET_SYSERR;
1572 GNUNET_free (op_name);
1574 /* Get preference */
1575 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1576 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1577 sec_name, op_name, &pref))
1579 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1580 op_counter, op_name, e->id);
1581 GNUNET_free (op_name);
1582 return GNUNET_SYSERR;
1585 if (0 == (o->pref_type = parse_preference_string(pref)))
1587 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1588 op_counter, op_name, e->id);
1589 GNUNET_free (op_name);
1591 return GNUNET_SYSERR;
1594 GNUNET_free (op_name);
1596 /* Get feedback delay */
1597 GNUNET_asprintf(&op_name, "op-%u-feedback_delay", op_counter);
1598 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
1599 sec_name, op_name, &o->feedback_delay))
1601 fprintf (stderr, "Using feedback delay %llu in operation %u `%s' in episode %u\n",
1602 (long long unsigned int) o->feedback_delay.rel_value_us,
1603 op_counter, op_name, e->id);
1606 o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
1607 GNUNET_free (op_name);
1609 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1610 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1611 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1612 GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
1619 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1623 const struct GNUNET_CONFIGURATION_Handle *cfg)
1629 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1630 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1631 sec_name, op_name, &o->peer_id))
1633 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1634 op_counter, "STOP_SET_PREFERENCE", op_name);
1635 GNUNET_free (op_name);
1636 return GNUNET_SYSERR;
1638 GNUNET_free (op_name);
1641 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1642 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1643 sec_name, op_name, &o->address_id))
1645 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1646 op_counter, "STOP_SET_PREFERENCE", op_name);
1647 GNUNET_free (op_name);
1648 return GNUNET_SYSERR;
1650 GNUNET_free (op_name);
1652 /* Get preference */
1653 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1654 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1655 sec_name, op_name, &pref))
1657 fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
1658 op_counter, "STOP_SET_PREFERENCE", op_name);
1659 GNUNET_free (op_name);
1660 return GNUNET_SYSERR;
1663 if (0 == (o->pref_type = parse_preference_string(pref)))
1665 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1666 op_counter, op_name, e->id);
1667 GNUNET_free (op_name);
1669 return GNUNET_SYSERR;
1672 GNUNET_free (op_name);
1674 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1675 "Found operation %s: [%llu:%llu]: %s\n",
1676 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1677 GNUNET_ATS_print_preference_type(o->pref_type));
1682 static enum GNUNET_ATS_Property
1683 parse_property_string (const char *str)
1685 enum GNUNET_ATS_Property c;
1687 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1688 if (0 == strcmp(str,
1689 GNUNET_ATS_print_property_type (c)))
1696 load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
1700 const struct GNUNET_CONFIGURATION_Handle *cfg)
1707 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1708 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1709 sec_name, op_name, &o->peer_id))
1711 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1712 op_counter, "START_SET_PROPERTY", op_name);
1713 GNUNET_free (op_name);
1714 return GNUNET_SYSERR;
1716 GNUNET_free (op_name);
1719 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1720 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1721 sec_name, op_name, &o->address_id))
1723 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1724 op_counter, "START_SET_PROPERTY", op_name);
1725 GNUNET_free (op_name);
1726 return GNUNET_SYSERR;
1728 GNUNET_free (op_name);
1731 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1732 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1733 sec_name, op_name, &type)) )
1735 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1736 op_counter, "START_SET_PROPERTY", op_name);
1737 GNUNET_free (op_name);
1738 return GNUNET_SYSERR;
1741 /* Load arguments for set_rate, start_send, set_preference */
1742 if (0 == strcmp (type, "constant"))
1744 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1746 else if (0 == strcmp (type, "linear"))
1748 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1750 else if (0 == strcmp (type, "sinus"))
1752 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1754 else if (0 == strcmp (type, "random"))
1756 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1760 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1761 op_counter, op_name, e->id);
1763 GNUNET_free (op_name);
1764 return GNUNET_SYSERR;
1767 GNUNET_free (op_name);
1771 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1772 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1773 sec_name, op_name, &o->base_rate))
1775 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1776 op_counter, op_name, e->id);
1777 GNUNET_free (op_name);
1778 return GNUNET_SYSERR;
1780 GNUNET_free (op_name);
1784 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1785 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1786 sec_name, op_name, &o->max_rate))
1788 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1789 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1790 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1792 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1793 op_counter, op_name, e->id);
1794 GNUNET_free (op_name);
1795 return GNUNET_SYSERR;
1798 GNUNET_free (op_name);
1801 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1802 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1803 sec_name, op_name, &o->period))
1805 o->period = e->duration;
1807 GNUNET_free (op_name);
1810 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1811 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1812 sec_name, op_name, &o->frequency))
1814 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1815 op_counter, op_name, e->id);
1816 GNUNET_free (op_name);
1817 return GNUNET_SYSERR;
1819 GNUNET_free (op_name);
1821 /* Get preference */
1822 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1823 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1824 sec_name, op_name, &prop))
1826 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1827 op_counter, op_name, e->id);
1828 GNUNET_free (op_name);
1829 GNUNET_free_non_null (prop);
1830 return GNUNET_SYSERR;
1833 if (0 == (o->prop_type = parse_property_string(prop)))
1835 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1836 op_counter, op_name, e->id);
1837 GNUNET_free (op_name);
1839 return GNUNET_SYSERR;
1843 GNUNET_free (op_name);
1845 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1846 "Found operation %s: [%llu:%llu] %s = %llu\n",
1847 "START_SET_PROPERTY", o->peer_id, o->address_id,
1848 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1854 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1858 const struct GNUNET_CONFIGURATION_Handle *cfg)
1864 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1865 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1866 sec_name, op_name, &o->peer_id))
1868 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1869 op_counter, "STOP_SET_PROPERTY", op_name);
1870 GNUNET_free (op_name);
1871 return GNUNET_SYSERR;
1873 GNUNET_free (op_name);
1876 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1877 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1878 sec_name, op_name, &o->address_id))
1880 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1881 op_counter, "STOP_SET_PROPERTY", op_name);
1882 GNUNET_free (op_name);
1883 return GNUNET_SYSERR;
1885 GNUNET_free (op_name);
1888 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1889 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1890 sec_name, op_name, &pref))
1892 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
1893 op_counter, "STOP_SET_PROPERTY", op_name);
1894 GNUNET_free (op_name);
1895 GNUNET_free_non_null (pref);
1896 return GNUNET_SYSERR;
1899 if (0 == (o->prop_type = parse_property_string(pref)))
1901 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1902 op_counter, op_name, e->id);
1903 GNUNET_free (op_name);
1904 GNUNET_free_non_null (pref);
1905 return GNUNET_SYSERR;
1909 GNUNET_free (op_name);
1911 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1912 "Found operation %s: [%llu:%llu] %s\n",
1913 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
1914 GNUNET_ATS_print_property_type (o->prop_type));
1921 load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
1925 const struct GNUNET_CONFIGURATION_Handle *cfg)
1930 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1931 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1932 sec_name, op_name, &o->peer_id))
1934 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1935 op_counter, "START_REQUEST", op_name);
1936 GNUNET_free (op_name);
1937 return GNUNET_SYSERR;
1939 GNUNET_free (op_name);
1944 load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
1948 const struct GNUNET_CONFIGURATION_Handle *cfg)
1953 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1954 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1955 sec_name, op_name, &o->peer_id))
1957 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1958 op_counter, "STOP_REQUEST", op_name);
1959 GNUNET_free (op_name);
1960 return GNUNET_SYSERR;
1962 GNUNET_free (op_name);
1968 load_episode (struct Experiment *e, struct Episode *cur,
1969 struct GNUNET_CONFIGURATION_Handle *cfg)
1971 struct GNUNET_ATS_TEST_Operation *o;
1977 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n",cur->id);
1978 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
1982 /* Load operation */
1983 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
1984 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1985 sec_name, op_name, &op))
1987 GNUNET_free (op_name);
1990 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
1991 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
1994 /* operations = set_rate, start_send, stop_send, set_preference */
1995 if (0 == strcmp (op, "address_add"))
1997 o->type = SOLVER_OP_ADD_ADDRESS;
1998 res = load_op_add_address (o, cur,
1999 op_counter, sec_name, cfg);
2001 else if (0 == strcmp (op, "address_del"))
2003 o->type = SOLVER_OP_DEL_ADDRESS;
2004 res = load_op_del_address (o, cur,
2005 op_counter, sec_name, cfg);
2007 else if (0 == strcmp (op, "start_set_property"))
2009 o->type = SOLVER_OP_START_SET_PROPERTY;
2010 res = load_op_start_set_property (o, cur,
2011 op_counter, sec_name, cfg);
2013 else if (0 == strcmp (op, "stop_set_property"))
2015 o->type = SOLVER_OP_STOP_SET_PROPERTY;
2016 res = load_op_stop_set_property (o, cur,
2017 op_counter, sec_name, cfg);
2019 else if (0 == strcmp (op, "start_set_preference"))
2021 o->type = SOLVER_OP_START_SET_PREFERENCE;
2022 res = load_op_start_set_preference (o, cur,
2023 op_counter, sec_name, cfg);
2025 else if (0 == strcmp (op, "stop_set_preference"))
2027 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
2028 res = load_op_stop_set_preference (o, cur,
2029 op_counter, sec_name, cfg);
2031 else if (0 == strcmp (op, "start_request"))
2033 o->type = SOLVER_OP_START_REQUEST;
2034 res = load_op_start_request (o, cur,
2035 op_counter, sec_name, cfg);
2037 else if (0 == strcmp (op, "stop_request"))
2039 o->type = SOLVER_OP_STOP_REQUEST;
2040 res = load_op_stop_request(o, cur,
2041 op_counter, sec_name, cfg);
2045 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
2046 op_counter, op, cur->id);
2047 res = GNUNET_SYSERR;
2051 GNUNET_free (op_name);
2053 if (GNUNET_SYSERR == res)
2056 GNUNET_free (sec_name);
2057 return GNUNET_SYSERR;
2060 GNUNET_CONTAINER_DLL_insert_tail (cur->head,cur->tail, o);
2063 GNUNET_free (sec_name);
2068 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
2072 struct GNUNET_TIME_Relative e_duration;
2073 struct Episode *cur;
2074 struct Episode *last;
2080 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
2081 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
2082 sec_name, "duration", &e_duration))
2084 GNUNET_free (sec_name);
2088 cur = GNUNET_new (struct Episode);
2089 cur->duration = e_duration;
2090 cur->id = e_counter;
2092 if (GNUNET_OK != load_episode (e, cur, cfg))
2094 GNUNET_free (sec_name);
2096 return GNUNET_SYSERR;
2099 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2101 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
2103 /* Update experiment */
2105 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
2106 /* Put in linked list */
2112 GNUNET_free (sec_name);
2120 timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
2122 struct Experiment *e = cls;
2123 e->experiment_timeout_task = NULL;
2124 fprintf (stderr, "Experiment timeout!\n");
2126 if (NULL != e->episode_timeout_task)
2128 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2129 e->episode_timeout_task = NULL;
2132 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
2136 struct ATS_Address *
2137 create_ats_address (const struct GNUNET_PeerIdentity *peer,
2138 const char *plugin_name,
2139 const void *plugin_addr,
2140 size_t plugin_addr_len,
2141 uint32_t session_id,
2144 struct ATS_Address *aa = NULL;
2146 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len + strlen (plugin_name) + 1);
2147 aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
2148 aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
2149 aa->atsi[0].value = htonl (network);
2153 aa->addr_len = plugin_addr_len;
2155 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2156 memcpy (&aa[1], plugin_addr, plugin_addr_len);
2157 memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2158 aa->session_id = session_id;
2166 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2169 struct TestAddress *a;
2172 if (NULL == (p = find_peer_by_id (op->peer_id)))
2174 p = GNUNET_new (struct TestPeer);
2175 p->id = op->peer_id;
2176 p->assigned_bw_in = 0;
2177 p->assigned_bw_out = 0;
2178 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2179 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2181 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2182 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2185 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2188 if (NULL != (find_address_by_id (p, op->address_id)))
2190 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2191 op->address_id, op->peer_id);
2195 a = GNUNET_new (struct TestAddress);
2196 a->aid = op->address_id;
2197 a->network = op->address_network;
2198 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2199 strlen (op->address) + 1, op->address_session, op->address_network);
2200 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2201 GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
2203 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2204 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2206 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2207 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2209 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding address %u for peer %u in network `%s'\n",
2210 op->address_id, op->peer_id, GNUNET_ATS_print_network_type(a->network));
2212 sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
2218 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2221 struct TestAddress *a;
2222 struct PropertyGenerator *pg;
2224 if (NULL == (p = find_peer_by_id (op->peer_id)))
2227 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2228 "Deleting address for unknown peer %u\n", op->peer_id);
2232 if (NULL == (a =find_address_by_id (p, op->address_id)))
2235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2236 "Deleting address for unknown peer %u\n", op->peer_id);
2240 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2242 GNUNET_ATS_solver_generate_property_stop (pg);
2245 GNUNET_assert (GNUNET_YES ==
2246 GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
2249 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2250 "Removing address %u for peer %u\n",
2254 sh->sf->s_del (sh->sf->cls, a->ats_addr, GNUNET_NO);
2258 GNUNET_ATS_solver_logging_now (l);
2260 GNUNET_CONTAINER_DLL_remove(p->addr_head, p->addr_tail, a);
2262 GNUNET_free_non_null(a->ats_addr->atsi);
2263 GNUNET_free (a->ats_addr);
2269 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2271 struct PropertyGenerator *pg;
2273 struct TestAddress *a;
2275 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2277 GNUNET_ATS_solver_generate_property_stop (pg);
2281 if (NULL == (p = find_peer_by_id (op->peer_id)))
2284 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2285 "Starting property generation for unknown peer %u\n", op->peer_id);
2289 if (NULL == (a = find_address_by_id (p, op->address_id)))
2292 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2293 "Setting property for unknown address %u\n", op->peer_id);
2297 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2309 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2311 struct PropertyGenerator *pg = find_prop_gen(op->peer_id, op->address_id,
2315 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2316 "Stopping preference generation for peer %u address %u\n", op->peer_id,
2318 GNUNET_ATS_solver_generate_property_stop (pg);
2322 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2323 "Cannot find preference generator for peer %u address %u\n",
2324 op->peer_id, op->address_id);
2330 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2332 struct PreferenceGenerator *pg;
2333 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2335 GNUNET_ATS_solver_generate_preferences_stop (pg);
2339 if (NULL == (find_peer_by_id (op->peer_id)))
2342 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2343 "Starting preference generation for unknown peer %u\n", op->peer_id);
2347 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2360 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2362 struct PreferenceGenerator *pg = find_pref_gen(op->peer_id,
2366 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2367 "Stopping property generation for peer %u address %u\n", op->peer_id,
2369 GNUNET_ATS_solver_generate_preferences_stop (pg);
2373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2374 "Cannot find preference generator for peer %u address %u\n",
2375 op->peer_id, op->address_id);
2382 enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2385 const struct ATS_Address *res;
2387 if (NULL == (p = find_peer_by_id (op->peer_id)))
2390 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2391 "Requesting address for unknown peer %u\n", op->peer_id);
2395 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2397 p->is_requested = GNUNET_YES;
2399 res = sh->sf->s_get (sh->sf->cls, &p->peer_id);
2402 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Suggested address for peer %u: %llu %llu\n",
2404 res->assigned_bw_in,
2405 res->assigned_bw_out);
2407 GNUNET_ATS_solver_logging_now (l);
2412 enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
2416 if (NULL == (p = find_peer_by_id (op->peer_id)))
2419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2420 "Requesting address for unknown peer %u\n", op->peer_id);
2426 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop requesting address for peer %u\n",
2428 p->is_requested = GNUNET_NO;
2429 p->assigned_bw_in = 0;
2430 p->assigned_bw_out = 0;
2431 sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
2435 GNUNET_ATS_solver_logging_now (l);
2440 static void enforce_episode (struct Episode *ep)
2442 struct GNUNET_ATS_TEST_Operation *cur;
2443 for (cur = ep->head; NULL != cur; cur = cur->next)
2445 switch (cur->type) {
2446 case SOLVER_OP_ADD_ADDRESS:
2447 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2448 print_op (cur->type), cur->peer_id, cur->address_id);
2449 enforce_add_address (cur);
2451 case SOLVER_OP_DEL_ADDRESS:
2452 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2453 print_op (cur->type), cur->peer_id, cur->address_id);
2454 enforce_del_address (cur);
2456 case SOLVER_OP_START_SET_PROPERTY:
2457 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2458 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2459 enforce_start_property (cur);
2461 case SOLVER_OP_STOP_SET_PROPERTY:
2462 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2463 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2464 enforce_stop_property (cur);
2466 case SOLVER_OP_START_SET_PREFERENCE:
2467 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2468 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2469 enforce_start_preference (cur);
2471 case SOLVER_OP_STOP_SET_PREFERENCE:
2472 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2473 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2474 enforce_stop_preference (cur);
2476 case SOLVER_OP_START_REQUEST:
2477 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2478 print_op (cur->type), cur->peer_id);
2479 enforce_start_request (cur);
2481 case SOLVER_OP_STOP_REQUEST:
2482 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2483 print_op (cur->type), cur->peer_id);
2484 enforce_stop_request (cur);
2493 timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
2495 struct Experiment *e = cls;
2496 e->episode_timeout_task = NULL;
2497 if (NULL != e->ep_done_cb)
2498 e->ep_done_cb (e->cur);
2500 /* Scheduling next */
2501 e->cur = e->cur->next;
2505 fprintf (stderr, "Last episode done!\n");
2506 if (NULL != e->experiment_timeout_task)
2508 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2509 e->experiment_timeout_task = NULL;
2511 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
2515 fprintf (stderr, "Running episode %u with timeout %s\n",
2517 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2518 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2519 &timeout_episode, e);
2520 enforce_episode(e->cur);
2527 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2528 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
2529 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
2531 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2532 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
2533 e->e_done_cb = e_done_cb;
2534 e->ep_done_cb = ep_done_cb;
2535 e->start_time = GNUNET_TIME_absolute_get();
2537 /* Start total time out */
2538 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2539 &timeout_experiment, e);
2542 if (NULL == e->start)
2549 fprintf (stderr, "Running episode %u with timeout %s\n",
2551 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2552 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2553 &timeout_episode, e);
2554 enforce_episode(e->cur);
2559 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2561 if (NULL != e->experiment_timeout_task)
2563 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2564 e->experiment_timeout_task = NULL;
2566 if (NULL != e->episode_timeout_task)
2568 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2569 e->episode_timeout_task = NULL;
2573 GNUNET_CONFIGURATION_destroy(e->cfg);
2576 free_experiment (e);
2581 GNUNET_ATS_solvers_experimentation_load (char *filename)
2583 struct Experiment *e;
2584 struct GNUNET_CONFIGURATION_Handle *cfg;
2587 cfg = GNUNET_CONFIGURATION_create();
2588 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2590 fprintf (stderr, "Failed to load `%s'\n", filename);
2591 GNUNET_CONFIGURATION_destroy (cfg);
2595 e = create_experiment ();
2597 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2600 fprintf (stderr, "Invalid %s \n", "name");
2601 free_experiment (e);
2605 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2607 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2608 "log_prefix", &e->log_prefix))
2610 fprintf (stderr, "Invalid %s \n", "log_prefix");
2611 free_experiment (e);
2615 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2618 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2619 "log_output_dir", &e->log_output_dir))
2621 e->log_output_dir = NULL;
2624 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging output directory: `%s'\n",
2628 if (GNUNET_SYSERR == (e->log_append_time_stamp = GNUNET_CONFIGURATION_get_value_yesno(cfg,
2629 "experiment", "log_append_time_stamp")))
2630 e->log_append_time_stamp = GNUNET_YES;
2631 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging append timestamp: `%s'\n",
2632 (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
2635 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2636 "cfg_file", &e->cfg_file))
2638 fprintf (stderr, "Invalid %s \n", "cfg_file");
2639 free_experiment (e);
2644 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n", e->cfg_file);
2645 e->cfg = GNUNET_CONFIGURATION_create();
2646 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2648 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2649 free_experiment (e);
2655 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2656 "log_freq", &e->log_freq))
2658 fprintf (stderr, "Invalid %s \n", "log_freq");
2659 free_experiment (e);
2663 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2664 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
2666 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2667 "max_duration", &e->max_duration))
2669 fprintf (stderr, "Invalid %s", "max_duration");
2670 free_experiment (e);
2674 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2675 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
2677 if (GNUNET_SYSERR == load_episodes (e, cfg))
2679 GNUNET_ATS_solvers_experimentation_stop (e);
2680 GNUNET_CONFIGURATION_destroy (cfg);
2682 fprintf (stderr, "Failed to load experiment\n");
2685 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded %u episodes with total duration %s\n",
2687 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
2689 GNUNET_CONFIGURATION_destroy (cfg);
2700 free_all_it (void *cls,
2701 const struct GNUNET_PeerIdentity *key,
2704 struct ATS_Address *address = value;
2705 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (sh->env.addresses,
2707 GNUNET_free (address);
2713 GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2715 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2717 GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
2719 GAS_normalization_stop();
2721 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
2724 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
2725 GNUNET_free (sh->plugin);
2731 * Load quotas for networks from configuration
2733 * @param cfg configuration handle
2734 * @param out_dest where to write outbound quotas
2735 * @param in_dest where to write inbound quotas
2736 * @param dest_length length of inbound and outbound arrays
2737 * @return number of networks loaded
2740 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2741 unsigned long long *out_dest,
2742 unsigned long long *in_dest,
2745 char * entry_in = NULL;
2746 char * entry_out = NULL;
2747 char * quota_out_str;
2748 char * quota_in_str;
2752 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
2756 GNUNET_asprintf (&entry_out,
2758 GNUNET_ATS_print_network_type (c));
2759 GNUNET_asprintf (&entry_in,
2761 GNUNET_ATS_print_network_type (c));
2764 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
2767 if (0 == strcmp(quota_out_str, BIG_M_STRING))
2769 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2772 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
2774 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
2777 if (GNUNET_NO == res)
2779 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2780 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2781 GNUNET_ATS_print_network_type (c),
2783 GNUNET_ATS_DefaultBandwidth);
2784 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2788 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2789 "Outbound quota configure for network `%s' is %llu\n",
2790 GNUNET_ATS_print_network_type (c),
2793 GNUNET_free (quota_out_str);
2797 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2798 _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
2799 GNUNET_ATS_print_network_type (c),
2800 GNUNET_ATS_DefaultBandwidth);
2801 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2805 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
2808 if (0 == strcmp(quota_in_str, BIG_M_STRING))
2810 in_dest[c] = GNUNET_ATS_MaxBandwidth;
2813 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
2815 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
2818 if (GNUNET_NO == res)
2820 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2821 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2822 GNUNET_ATS_print_network_type (c),
2824 GNUNET_ATS_DefaultBandwidth);
2825 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
2829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2830 "Inbound quota configured for network `%s' is %llu\n",
2831 GNUNET_ATS_print_network_type (c),
2834 GNUNET_free (quota_in_str);
2838 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2839 _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
2840 GNUNET_ATS_print_network_type (c),
2841 GNUNET_ATS_DefaultBandwidth);
2842 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2844 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2845 "Loaded quota for network `%s' (in/out): %llu %llu\n",
2846 GNUNET_ATS_print_network_type (c),
2849 GNUNET_free (entry_out);
2850 GNUNET_free (entry_in);
2852 return GNUNET_ATS_NetworkTypeCount;
2857 * Information callback for the solver
2859 * @param cls the closure
2860 * @param op the solver operation
2861 * @param stat status of the solver operation
2862 * @param add additional solver information
2865 solver_info_cb (void *cls,
2866 enum GAS_Solver_Operation op,
2867 enum GAS_Solver_Status stat,
2868 enum GAS_Solver_Additional_Information add)
2873 add_info = "GAS_INFO_NONE";
2876 add_info = "GAS_INFO_MLP_FULL";
2878 case GAS_INFO_UPDATED:
2879 add_info = "GAS_INFO_MLP_UPDATED";
2881 case GAS_INFO_PROP_ALL:
2882 add_info = "GAS_INFO_PROP_ALL";
2884 case GAS_INFO_PROP_SINGLE:
2885 add_info = "GAS_INFO_PROP_SINGLE";
2888 add_info = "INVALID";
2894 case GAS_OP_SOLVE_START:
2895 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2896 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
2897 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2899 case GAS_OP_SOLVE_STOP:
2900 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2901 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
2902 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2905 case GAS_OP_SOLVE_SETUP_START:
2906 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2907 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
2908 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2911 case GAS_OP_SOLVE_SETUP_STOP:
2912 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2913 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
2914 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2917 case GAS_OP_SOLVE_MLP_LP_START:
2918 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2919 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
2920 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2922 case GAS_OP_SOLVE_MLP_LP_STOP:
2923 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2924 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
2925 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2928 case GAS_OP_SOLVE_MLP_MLP_START:
2929 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2930 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
2931 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2933 case GAS_OP_SOLVE_MLP_MLP_STOP:
2934 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2935 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
2936 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2938 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
2939 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2940 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
2941 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2943 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
2944 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2945 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
2946 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2954 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
2956 struct GNUNET_TIME_Relative duration;
2958 static struct PreferenceGenerator *pg;
2960 if ( (0 == address->assigned_bw_out) && (0 == address->assigned_bw_in) )
2962 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2963 "Solver notified to disconnect peer `%s'\n",
2964 GNUNET_i2s (&address->peer));
2966 p = find_peer_by_pid(&address->peer);
2969 p->assigned_bw_out = address->assigned_bw_out;
2970 p->assigned_bw_in = address->assigned_bw_in;
2972 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
2974 if (pg->peer == p->id)
2976 duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
2977 delta = duration.rel_value_us * pg->last_assigned_bw_out;
2978 pg->feedback_bw_out_acc += delta;
2980 delta = duration.rel_value_us * pg->last_assigned_bw_in;
2981 pg->feedback_bw_in_acc += delta;
2983 pg->last_assigned_bw_in = address->assigned_bw_in;
2984 pg->last_assigned_bw_out = address->assigned_bw_out;
2985 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
2989 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2990 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
2991 GNUNET_i2s (&address->peer),
2993 address->assigned_bw_out,
2994 address->assigned_bw_in);
2997 GNUNET_ATS_solver_logging_now (l);
3003 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3006 if (GNUNET_YES == opt_disable_normalization)
3008 if (NULL == (p = find_peer_by_pid (id)))
3013 return GAS_preference_get_by_peer (NULL,
3018 struct SolverHandle *
3019 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3021 struct SolverHandle *sh;
3025 case GNUNET_ATS_SOLVER_PROPORTIONAL:
3026 solver_str = "proportional";
3028 case GNUNET_ATS_SOLVER_MLP:
3031 case GNUNET_ATS_SOLVER_RIL:
3040 sh = GNUNET_new (struct SolverHandle);
3041 GNUNET_asprintf (&sh->plugin,
3042 "libgnunet_plugin_ats_%s",
3044 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
3046 /* setup environment */
3047 sh->env.cfg = e->cfg;
3048 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
3049 sh->env.addresses = sh->addresses;
3050 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
3051 sh->env.get_preferences = &get_preferences_cb;
3052 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
3053 sh->env.info_cb = &solver_info_cb;
3054 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
3056 /* start normalization */
3057 GAS_normalization_start ();
3060 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
3061 sh->env.out_quota, sh->env.in_quota, GNUNET_ATS_NetworkTypeCount))
3064 GNUNET_free (sh->plugin);
3070 sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
3073 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
3075 GNUNET_free (sh->plugin);
3087 struct TestPeer *cur;
3088 struct TestPeer *next;
3090 struct TestAddress *cur_a;
3091 struct TestAddress *next_a;
3094 GNUNET_ATS_solver_logging_stop (l);
3096 /* Stop all preference generation */
3097 GNUNET_ATS_solver_generate_preferences_stop_all ();
3099 /* Stop all property generation */
3100 GNUNET_ATS_solver_generate_property_stop_all ();
3104 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
3105 GNUNET_ATS_solver_logging_eval (l);
3109 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
3110 GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
3116 GNUNET_ATS_solver_logging_free (l);
3120 /* Clean up experiment */
3123 GNUNET_ATS_solvers_experimentation_stop (e);
3128 while (NULL != (cur = next))
3131 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3132 next_a = cur->addr_head;
3133 while (NULL != (cur_a = next_a))
3135 next_a = cur_a->next;
3136 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3137 GNUNET_free (cur_a);
3143 GNUNET_ATS_solvers_solver_stop (sh);
3152 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
3154 if (GNUNET_OK == success)
3155 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3156 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3158 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3160 GNUNET_SCHEDULER_add_now (&done, NULL);
3164 episode_done_cb (struct Episode *ep)
3166 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3179 GNUNET_ATS_solvers_experimentation_stop (e);
3184 GNUNET_ATS_solvers_solver_stop (sh);
3190 run (void *cls, char * const *args, const char *cfgfile,
3191 const struct GNUNET_CONFIGURATION_Handle *cfg)
3193 enum GNUNET_ATS_Solvers solver;
3196 if (NULL == opt_exp_file)
3198 fprintf (stderr, "No experiment given ...\n");
3204 if (NULL == opt_solver)
3206 fprintf (stderr, "No solver given ...\n");
3212 if (0 == strcmp(opt_solver, "mlp"))
3214 solver = GNUNET_ATS_SOLVER_MLP;
3216 else if (0 == strcmp(opt_solver, "proportional"))
3218 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3220 else if (0 == strcmp(opt_solver, "ril"))
3222 solver = GNUNET_ATS_SOLVER_RIL;
3226 fprintf (stderr, "No solver given ...");
3232 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3233 default_properties[c] = DEFAULT_REL_QUALITY;
3235 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3236 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3238 /* load experiment */
3239 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3240 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3243 fprintf (stderr, "Failed to load experiment ...\n");
3250 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3251 sh = GNUNET_ATS_solvers_solver_start (solver);
3254 fprintf (stderr, "Failed to start solver ...\n");
3261 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3262 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3264 /* run experiment */
3265 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3266 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3267 experiment_done_cb);
3274 * Main function of the benchmark
3276 * @param argc argument count
3277 * @param argv argument values
3280 main (int argc, char *argv[])
3282 opt_exp_file = NULL;
3284 opt_log = GNUNET_NO;
3285 opt_save = GNUNET_NO;
3289 static struct GNUNET_GETOPT_CommandLineOption options[] =
3291 { 's', "solver", NULL,
3292 gettext_noop ("solver to use"),
3293 1, &GNUNET_GETOPT_set_string, &opt_solver},
3294 { 'e', "experiment", NULL,
3295 gettext_noop ("experiment to use"),
3296 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
3297 { 'V', "verbose", NULL,
3298 gettext_noop ("be verbose"),
3299 0, &GNUNET_GETOPT_set_one, &opt_verbose},
3300 { 'p', "print", NULL,
3301 gettext_noop ("print logging"),
3302 0, &GNUNET_GETOPT_set_one, &opt_print},
3303 { 'f', "file", NULL,
3304 gettext_noop ("save logging to disk"),
3305 0, &GNUNET_GETOPT_set_one, &opt_save},
3307 gettext_noop ("disable normalization"),
3308 0, &GNUNET_GETOPT_set_one, &opt_disable_normalization},
3309 GNUNET_GETOPT_OPTION_END
3312 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3313 NULL, options, &run, argv[0]);
3317 /* end of file ats-testing-experiment.c*/