2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
27 #include "gnunet_util_lib.h"
28 #include "gnunet-ats-solver-eval.h"
29 #include "gnunet-service-ats_normalization.h"
30 #include "gnunet-service-ats_preferences.c"
32 #define BIG_M_STRING "unlimited"
35 * Handle for statistics.
37 struct GNUNET_STATISTICS_Handle *GSA_stats;
40 static struct Experiment *e;
42 static struct LoggingHandle *l;
44 static struct SolverHandle *sh;
46 static struct TestPeer *peer_head;
48 static struct TestPeer *peer_tail;
50 static double default_properties[GNUNET_ATS_PropertyCount];
51 static double default_preferences[GNUNET_ATS_PreferenceCount];
54 * cmd option -e: experiment file
56 static char *opt_exp_file;
58 static char *opt_solver;
61 * cmd option -l: enable logging
66 * cmd option -p: enable plots
71 * cmd option -v: verbose logs
73 static int opt_verbose;
76 * cmd option -p: print logs
81 * cmd option -d: disable normalization
83 static int opt_disable_normalization;
92 print_generator_type (enum GeneratorType g)
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 == GNUNET_memcmp (&cur->peer_id, pid))
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)
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)
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",
863 set_feedback_task (void *cls)
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)
939 struct PreferenceGenerator *pg = cls;
944 if (NULL == (p = find_peer_by_id (pg->peer)))
947 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
948 "Setting preference for unknown peer %u\n", pg->peer);
952 pref_value = get_preference (pg);
954 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
955 pg->pref_bw_old = pref_value;
957 case GNUNET_ATS_PREFERENCE_LATENCY:
958 pg->pref_latency_old = pref_value;
964 p->pref_abs[pg->kind] = pref_value;
966 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
967 "Setting preference for peer [%u] for client %p pref %s to %f\n",
968 pg->peer, NULL + (pg->client_id),
969 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
971 if (GNUNET_YES == opt_disable_normalization)
973 p->pref_abs[pg->kind] = pref_value;
974 p->pref_norm[pg->kind] = pref_value;
975 sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
978 update_preference (NULL + (pg->client_id),
983 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
989 static struct PreferenceGenerator *
990 find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
992 struct PreferenceGenerator *cur;
993 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
994 if (cur->peer == peer)
996 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
1003 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
1005 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
1007 if (NULL != pg->feedback_task)
1009 GNUNET_SCHEDULER_cancel (pg->feedback_task);
1010 pg->feedback_task = NULL;
1013 if (NULL != pg->set_task)
1015 GNUNET_SCHEDULER_cancel (pg->set_task);
1016 pg->set_task = NULL;
1018 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1019 "Removing old up preference generator peer [%u] `%s'\n",
1020 pg->peer, GNUNET_ATS_print_preference_type(pg->kind));
1026 static struct TestAddress*
1027 find_active_address (struct TestPeer *p)
1029 struct TestAddress *cur;
1030 for (cur = p->addr_head; NULL != cur; cur = cur->next)
1031 if (GNUNET_YES == cur->ats_addr->active)
1038 * Generate between the source master and the partner and set property with a
1039 * value depending on the generator.
1041 * @param peer source
1042 * @param address_id partner
1043 * @param client_id the client
1044 * @param type type of generator
1045 * @param base_value base value
1046 * @param value_rate maximum value
1047 * @param period duration of a period of generation (~ 1/frequency)
1048 * @param frequency how long to generate property
1049 * @param kind ATS preference to generate
1050 * @param feedback_frequency how often to give feedback
1051 * @return the preference generator
1053 struct PreferenceGenerator *
1054 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
1055 unsigned int address_id,
1056 unsigned int client_id,
1057 enum GeneratorType type,
1058 long int base_value,
1059 long int value_rate,
1060 struct GNUNET_TIME_Relative period,
1061 struct GNUNET_TIME_Relative frequency,
1062 enum GNUNET_ATS_PreferenceKind kind,
1063 struct GNUNET_TIME_Relative feedback_frequency)
1065 struct PreferenceGenerator *pg;
1068 if (NULL == (p = find_peer_by_id (peer)))
1071 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1072 "Starting preference for unknown peer %u\n", peer);
1076 pg = GNUNET_new (struct PreferenceGenerator);
1077 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
1080 pg->client_id = client_id;
1082 pg->base_value = base_value;
1083 pg->max_value = value_rate;
1084 pg->duration_period = period;
1085 pg->frequency = frequency;
1086 pg->time_start = GNUNET_TIME_absolute_get();
1087 pg->feedback_frequency = feedback_frequency;
1090 case GNUNET_ATS_TEST_TG_CONSTANT:
1091 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1092 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
1093 print_generator_type (type), pg->peer,
1094 GNUNET_ATS_print_preference_type(kind),
1097 case GNUNET_ATS_TEST_TG_LINEAR:
1098 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1099 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
1100 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1101 base_value, value_rate);
1103 case GNUNET_ATS_TEST_TG_SINUS:
1104 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1105 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
1106 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1107 base_value, value_rate);
1109 case GNUNET_ATS_TEST_TG_RANDOM:
1110 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1111 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1112 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1113 base_value, value_rate);
1119 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1120 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != feedback_frequency.rel_value_us)
1122 struct TestAddress * addr = find_active_address(p);
1124 pg->last_assigned_bw_in = p->assigned_bw_in;
1125 pg->last_assigned_bw_out = p->assigned_bw_out;
1126 pg->feedback_bw_in_acc = 0;
1127 pg->feedback_bw_out_acc = 0;
1128 pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
1129 pg->feedback_delay_acc = 0;
1131 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
1132 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get();
1133 pg->feedback_last = GNUNET_TIME_absolute_get();
1134 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
1135 &set_feedback_task, pg);
1144 * Stop all preferences generators
1147 GNUNET_ATS_solver_generate_preferences_stop_all ()
1149 struct PreferenceGenerator *cur;
1150 struct PreferenceGenerator *next;
1151 next = pref_gen_head;
1152 for (cur = next; NULL != cur; cur = next)
1155 GNUNET_ATS_solver_generate_preferences_stop(cur);
1165 print_op (enum OperationType op)
1168 case SOLVER_OP_ADD_ADDRESS:
1169 return "ADD_ADDRESS";
1170 case SOLVER_OP_DEL_ADDRESS:
1171 return "DEL_ADDRESS";
1172 case SOLVER_OP_START_SET_PREFERENCE:
1173 return "START_SET_PREFERENCE";
1174 case SOLVER_OP_STOP_SET_PREFERENCE:
1175 return "STOP_STOP_PREFERENCE";
1176 case SOLVER_OP_START_SET_PROPERTY:
1177 return "START_SET_PROPERTY";
1178 case SOLVER_OP_STOP_SET_PROPERTY:
1179 return "STOP_SET_PROPERTY";
1180 case SOLVER_OP_START_REQUEST:
1181 return "START_REQUEST";
1182 case SOLVER_OP_STOP_REQUEST:
1183 return "STOP_REQUEST";
1191 static struct Experiment *
1192 create_experiment ()
1194 struct Experiment *e;
1195 e = GNUNET_new (struct Experiment);
1198 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1204 free_experiment (struct Experiment *e)
1206 struct Episode *cur;
1207 struct Episode *next;
1208 struct GNUNET_ATS_TEST_Operation *cur_o;
1209 struct GNUNET_ATS_TEST_Operation *next_o;
1212 for (cur = next; NULL != cur; cur = next)
1217 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1219 next_o = cur_o->next;
1220 GNUNET_free_non_null (cur_o->address);
1221 GNUNET_free_non_null (cur_o->plugin);
1222 GNUNET_free (cur_o);
1227 GNUNET_free_non_null (e->name);
1228 GNUNET_free_non_null (e->log_prefix);
1229 GNUNET_free_non_null (e->log_output_dir);
1230 GNUNET_free_non_null (e->cfg_file);
1236 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1240 const struct GNUNET_CONFIGURATION_Handle *cfg)
1246 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1247 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1248 sec_name, op_name, &o->peer_id))
1250 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1251 op_counter, "ADD_ADDRESS", op_name);
1252 GNUNET_free (op_name);
1253 return GNUNET_SYSERR;
1255 GNUNET_free (op_name);
1258 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1259 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1260 sec_name, op_name, &o->address_id))
1262 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1263 op_counter, "ADD_ADDRESS", op_name);
1264 GNUNET_free (op_name);
1265 return GNUNET_SYSERR;
1267 GNUNET_free (op_name);
1270 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1271 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1272 sec_name, op_name, &o->plugin))
1274 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1275 op_counter, "ADD_ADDRESS", op_name);
1276 GNUNET_free (op_name);
1277 return GNUNET_SYSERR;
1279 GNUNET_free (op_name);
1282 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1283 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1284 sec_name, op_name, &o->address))
1286 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1287 op_counter, "ADD_ADDRESS", op_name);
1288 GNUNET_free (op_name);
1289 return GNUNET_SYSERR;
1291 GNUNET_free (op_name);
1294 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1295 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1296 sec_name, op_name, &o->address_session))
1298 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1299 op_counter, "ADD_ADDRESS", op_name);
1300 GNUNET_free (op_name);
1301 return GNUNET_SYSERR;
1303 GNUNET_free (op_name);
1306 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
1307 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1308 sec_name, op_name, &op_network))
1310 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
1311 op_counter, "ADD_ADDRESS", op_name);
1312 GNUNET_free (op_name);
1313 return GNUNET_SYSERR;
1317 GNUNET_STRINGS_utf8_toupper (op_network,op_network);
1318 if (0 == strcmp(op_network, "UNSPECIFIED"))
1320 o->address_network = GNUNET_NT_UNSPECIFIED;
1322 else if (0 == strcmp(op_network, "LOOPBACK"))
1324 o->address_network = GNUNET_NT_LOOPBACK;
1326 else if (0 == strcmp(op_network, "LAN"))
1328 o->address_network = GNUNET_NT_LAN;
1330 else if (0 == strcmp(op_network, "WAN"))
1332 o->address_network = GNUNET_NT_WAN;
1334 else if (0 == strcmp(op_network, "WLAN"))
1336 o->address_network = GNUNET_NT_WLAN;
1338 else if (0 == strcmp(op_network, "BT"))
1340 o->address_network = GNUNET_NT_BT;
1344 fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1345 op_counter, "ADD_ADDRESS", op_name, op_network);
1346 GNUNET_free (op_network);
1347 GNUNET_free (op_name);
1348 return GNUNET_SYSERR;
1351 GNUNET_free (op_network);
1352 GNUNET_free (op_name);
1354 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1355 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1356 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1363 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1367 const struct GNUNET_CONFIGURATION_Handle *cfg)
1373 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1374 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1375 sec_name, op_name, &o->peer_id))
1377 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1378 op_counter, "DEL_ADDRESS", op_name);
1379 GNUNET_free (op_name);
1380 return GNUNET_SYSERR;
1382 GNUNET_free (op_name);
1385 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1386 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1387 sec_name, op_name, &o->address_id))
1389 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1390 op_counter, "DEL_ADDRESS", op_name);
1391 GNUNET_free (op_name);
1392 return GNUNET_SYSERR;
1394 GNUNET_free (op_name);
1398 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1399 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1400 sec_name, op_name, &o->plugin))
1402 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1403 op_counter, "DEL_ADDRESS", op_name);
1404 GNUNET_free (op_name);
1405 return GNUNET_SYSERR;
1407 GNUNET_free (op_name);
1410 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1411 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1412 sec_name, op_name, &o->address))
1414 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1415 op_counter, "DEL_ADDRESS", op_name);
1416 GNUNET_free (op_name);
1417 return GNUNET_SYSERR;
1419 GNUNET_free (op_name);
1422 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1423 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1424 sec_name, op_name, &o->address_session))
1426 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1427 op_counter, "DEL_ADDRESS", op_name);
1428 GNUNET_free (op_name);
1429 return GNUNET_SYSERR;
1431 GNUNET_free (op_name);
1434 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1435 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1436 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1442 static enum GNUNET_ATS_Property
1443 parse_preference_string (const char * str)
1446 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1448 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1449 if (0 == strcmp(str, props[c]))
1456 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1460 const struct GNUNET_CONFIGURATION_Handle *cfg)
1467 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1468 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1469 sec_name, op_name, &o->peer_id))
1471 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1472 op_counter, "START_SET_PREFERENCE", op_name);
1473 GNUNET_free (op_name);
1474 return GNUNET_SYSERR;
1476 GNUNET_free (op_name);
1479 GNUNET_asprintf(&op_name, "op-%u-client-id", op_counter);
1480 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1481 sec_name, op_name, &o->client_id))
1483 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1484 op_counter, "START_SET_PREFERENCE", op_name);
1485 GNUNET_free (op_name);
1486 return GNUNET_SYSERR;
1488 GNUNET_free (op_name);
1491 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1492 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1493 sec_name, op_name, &type)) )
1495 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1496 op_counter, "START_SET_PREFERENCE", op_name);
1497 GNUNET_free (op_name);
1498 return GNUNET_SYSERR;
1501 /* Load arguments for set_rate, start_send, set_preference */
1502 if (0 == strcmp (type, "constant"))
1504 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1506 else if (0 == strcmp (type, "linear"))
1508 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1510 else if (0 == strcmp (type, "sinus"))
1512 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1514 else if (0 == strcmp (type, "random"))
1516 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1520 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1521 op_counter, op_name, e->id);
1523 GNUNET_free (op_name);
1524 return GNUNET_SYSERR;
1527 GNUNET_free (op_name);
1531 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1532 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1533 sec_name, op_name, &o->base_rate))
1535 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1536 op_counter, op_name, e->id);
1537 GNUNET_free (op_name);
1538 return GNUNET_SYSERR;
1540 GNUNET_free (op_name);
1544 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1545 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1546 sec_name, op_name, &o->max_rate))
1548 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1549 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1550 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1552 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1553 op_counter, op_name, e->id);
1554 GNUNET_free (op_name);
1555 return GNUNET_SYSERR;
1558 GNUNET_free (op_name);
1561 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1562 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1563 sec_name, op_name, &o->period))
1565 o->period = e->duration;
1567 GNUNET_free (op_name);
1570 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1571 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1572 sec_name, op_name, &o->frequency))
1574 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1575 op_counter, op_name, e->id);
1576 GNUNET_free (op_name);
1577 return GNUNET_SYSERR;
1579 GNUNET_free (op_name);
1581 /* Get preference */
1582 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1583 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1584 sec_name, op_name, &pref))
1586 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1587 op_counter, op_name, e->id);
1588 GNUNET_free (op_name);
1589 return GNUNET_SYSERR;
1592 if (0 == (o->pref_type = parse_preference_string(pref)))
1594 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1595 op_counter, op_name, e->id);
1596 GNUNET_free (op_name);
1598 return GNUNET_SYSERR;
1601 GNUNET_free (op_name);
1603 /* Get feedback delay */
1604 GNUNET_asprintf(&op_name, "op-%u-feedback_delay", op_counter);
1605 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
1606 sec_name, op_name, &o->feedback_delay))
1608 fprintf (stderr, "Using feedback delay %llu in operation %u `%s' in episode %u\n",
1609 (long long unsigned int) o->feedback_delay.rel_value_us,
1610 op_counter, op_name, e->id);
1613 o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
1614 GNUNET_free (op_name);
1616 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1617 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1618 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1619 GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
1626 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1630 const struct GNUNET_CONFIGURATION_Handle *cfg)
1636 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1637 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1638 sec_name, op_name, &o->peer_id))
1640 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1641 op_counter, "STOP_SET_PREFERENCE", op_name);
1642 GNUNET_free (op_name);
1643 return GNUNET_SYSERR;
1645 GNUNET_free (op_name);
1648 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1649 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1650 sec_name, op_name, &o->address_id))
1652 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1653 op_counter, "STOP_SET_PREFERENCE", op_name);
1654 GNUNET_free (op_name);
1655 return GNUNET_SYSERR;
1657 GNUNET_free (op_name);
1659 /* Get preference */
1660 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1661 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1662 sec_name, op_name, &pref))
1664 fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
1665 op_counter, "STOP_SET_PREFERENCE", op_name);
1666 GNUNET_free (op_name);
1667 return GNUNET_SYSERR;
1670 if (0 == (o->pref_type = parse_preference_string(pref)))
1672 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1673 op_counter, op_name, e->id);
1674 GNUNET_free (op_name);
1676 return GNUNET_SYSERR;
1679 GNUNET_free (op_name);
1681 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1682 "Found operation %s: [%llu:%llu]: %s\n",
1683 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1684 GNUNET_ATS_print_preference_type(o->pref_type));
1689 static enum GNUNET_ATS_Property
1690 parse_property_string (const char *str)
1692 enum GNUNET_ATS_Property c;
1694 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1695 if (0 == strcmp(str,
1696 GNUNET_ATS_print_property_type (c)))
1703 load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
1707 const struct GNUNET_CONFIGURATION_Handle *cfg)
1714 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1715 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1716 sec_name, op_name, &o->peer_id))
1718 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1719 op_counter, "START_SET_PROPERTY", op_name);
1720 GNUNET_free (op_name);
1721 return GNUNET_SYSERR;
1723 GNUNET_free (op_name);
1726 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1727 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1728 sec_name, op_name, &o->address_id))
1730 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1731 op_counter, "START_SET_PROPERTY", op_name);
1732 GNUNET_free (op_name);
1733 return GNUNET_SYSERR;
1735 GNUNET_free (op_name);
1738 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1739 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1740 sec_name, op_name, &type)) )
1742 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1743 op_counter, "START_SET_PROPERTY", op_name);
1744 GNUNET_free (op_name);
1745 return GNUNET_SYSERR;
1748 /* Load arguments for set_rate, start_send, set_preference */
1749 if (0 == strcmp (type, "constant"))
1751 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1753 else if (0 == strcmp (type, "linear"))
1755 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1757 else if (0 == strcmp (type, "sinus"))
1759 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1761 else if (0 == strcmp (type, "random"))
1763 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1767 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1768 op_counter, op_name, e->id);
1770 GNUNET_free (op_name);
1771 return GNUNET_SYSERR;
1774 GNUNET_free (op_name);
1778 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1779 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1780 sec_name, op_name, &o->base_rate))
1782 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1783 op_counter, op_name, e->id);
1784 GNUNET_free (op_name);
1785 return GNUNET_SYSERR;
1787 GNUNET_free (op_name);
1791 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1792 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1793 sec_name, op_name, &o->max_rate))
1795 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1796 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1797 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1799 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1800 op_counter, op_name, e->id);
1801 GNUNET_free (op_name);
1802 return GNUNET_SYSERR;
1805 GNUNET_free (op_name);
1808 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1809 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1810 sec_name, op_name, &o->period))
1812 o->period = e->duration;
1814 GNUNET_free (op_name);
1817 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1818 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1819 sec_name, op_name, &o->frequency))
1821 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1822 op_counter, op_name, e->id);
1823 GNUNET_free (op_name);
1824 return GNUNET_SYSERR;
1826 GNUNET_free (op_name);
1828 /* Get preference */
1829 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1830 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1831 sec_name, op_name, &prop))
1833 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1834 op_counter, op_name, e->id);
1835 GNUNET_free (op_name);
1836 GNUNET_free_non_null (prop);
1837 return GNUNET_SYSERR;
1840 if (0 == (o->prop_type = parse_property_string(prop)))
1842 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1843 op_counter, op_name, e->id);
1844 GNUNET_free (op_name);
1846 return GNUNET_SYSERR;
1850 GNUNET_free (op_name);
1852 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1853 "Found operation %s: [%llu:%llu] %s = %llu\n",
1854 "START_SET_PROPERTY", o->peer_id, o->address_id,
1855 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1861 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1865 const struct GNUNET_CONFIGURATION_Handle *cfg)
1871 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1872 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1873 sec_name, op_name, &o->peer_id))
1875 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1876 op_counter, "STOP_SET_PROPERTY", op_name);
1877 GNUNET_free (op_name);
1878 return GNUNET_SYSERR;
1880 GNUNET_free (op_name);
1883 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1884 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1885 sec_name, op_name, &o->address_id))
1887 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1888 op_counter, "STOP_SET_PROPERTY", op_name);
1889 GNUNET_free (op_name);
1890 return GNUNET_SYSERR;
1892 GNUNET_free (op_name);
1895 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1896 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1897 sec_name, op_name, &pref))
1899 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
1900 op_counter, "STOP_SET_PROPERTY", op_name);
1901 GNUNET_free (op_name);
1902 GNUNET_free_non_null (pref);
1903 return GNUNET_SYSERR;
1906 if (0 == (o->prop_type = parse_property_string(pref)))
1908 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1909 op_counter, op_name, e->id);
1910 GNUNET_free (op_name);
1911 GNUNET_free_non_null (pref);
1912 return GNUNET_SYSERR;
1916 GNUNET_free (op_name);
1918 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1919 "Found operation %s: [%llu:%llu] %s\n",
1920 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
1921 GNUNET_ATS_print_property_type (o->prop_type));
1928 load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
1932 const struct GNUNET_CONFIGURATION_Handle *cfg)
1937 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1938 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1939 sec_name, op_name, &o->peer_id))
1941 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1942 op_counter, "START_REQUEST", op_name);
1943 GNUNET_free (op_name);
1944 return GNUNET_SYSERR;
1946 GNUNET_free (op_name);
1951 load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
1955 const struct GNUNET_CONFIGURATION_Handle *cfg)
1960 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1961 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1962 sec_name, op_name, &o->peer_id))
1964 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1965 op_counter, "STOP_REQUEST", op_name);
1966 GNUNET_free (op_name);
1967 return GNUNET_SYSERR;
1969 GNUNET_free (op_name);
1975 load_episode (struct Experiment *e, struct Episode *cur,
1976 struct GNUNET_CONFIGURATION_Handle *cfg)
1978 struct GNUNET_ATS_TEST_Operation *o;
1984 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n",cur->id);
1985 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
1989 /* Load operation */
1990 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
1991 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1992 sec_name, op_name, &op))
1994 GNUNET_free (op_name);
1997 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
1998 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
2001 /* operations = set_rate, start_send, stop_send, set_preference */
2002 if (0 == strcmp (op, "address_add"))
2004 o->type = SOLVER_OP_ADD_ADDRESS;
2005 res = load_op_add_address (o, cur,
2006 op_counter, sec_name, cfg);
2008 else if (0 == strcmp (op, "address_del"))
2010 o->type = SOLVER_OP_DEL_ADDRESS;
2011 res = load_op_del_address (o, cur,
2012 op_counter, sec_name, cfg);
2014 else if (0 == strcmp (op, "start_set_property"))
2016 o->type = SOLVER_OP_START_SET_PROPERTY;
2017 res = load_op_start_set_property (o, cur,
2018 op_counter, sec_name, cfg);
2020 else if (0 == strcmp (op, "stop_set_property"))
2022 o->type = SOLVER_OP_STOP_SET_PROPERTY;
2023 res = load_op_stop_set_property (o, cur,
2024 op_counter, sec_name, cfg);
2026 else if (0 == strcmp (op, "start_set_preference"))
2028 o->type = SOLVER_OP_START_SET_PREFERENCE;
2029 res = load_op_start_set_preference (o, cur,
2030 op_counter, sec_name, cfg);
2032 else if (0 == strcmp (op, "stop_set_preference"))
2034 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
2035 res = load_op_stop_set_preference (o, cur,
2036 op_counter, sec_name, cfg);
2038 else if (0 == strcmp (op, "start_request"))
2040 o->type = SOLVER_OP_START_REQUEST;
2041 res = load_op_start_request (o, cur,
2042 op_counter, sec_name, cfg);
2044 else if (0 == strcmp (op, "stop_request"))
2046 o->type = SOLVER_OP_STOP_REQUEST;
2047 res = load_op_stop_request(o, cur,
2048 op_counter, sec_name, cfg);
2052 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
2053 op_counter, op, cur->id);
2054 res = GNUNET_SYSERR;
2058 GNUNET_free (op_name);
2060 if (GNUNET_SYSERR == res)
2063 GNUNET_free (sec_name);
2064 return GNUNET_SYSERR;
2067 GNUNET_CONTAINER_DLL_insert_tail (cur->head,cur->tail, o);
2070 GNUNET_free (sec_name);
2075 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
2079 struct GNUNET_TIME_Relative e_duration;
2080 struct Episode *cur;
2081 struct Episode *last;
2087 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
2088 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
2089 sec_name, "duration", &e_duration))
2091 GNUNET_free (sec_name);
2095 cur = GNUNET_new (struct Episode);
2096 cur->duration = e_duration;
2097 cur->id = e_counter;
2099 if (GNUNET_OK != load_episode (e, cur, cfg))
2101 GNUNET_free (sec_name);
2103 return GNUNET_SYSERR;
2106 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2108 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
2110 /* Update experiment */
2112 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
2113 /* Put in linked list */
2119 GNUNET_free (sec_name);
2128 timeout_experiment (void *cls)
2130 struct Experiment *e = cls;
2132 e->experiment_timeout_task = NULL;
2133 fprintf (stderr, "Experiment timeout!\n");
2135 if (NULL != e->episode_timeout_task)
2137 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2138 e->episode_timeout_task = NULL;
2141 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
2145 struct ATS_Address *
2146 create_ats_address (const struct GNUNET_PeerIdentity *peer,
2147 const char *plugin_name,
2148 const void *plugin_addr,
2149 size_t plugin_addr_len,
2150 uint32_t session_id,
2153 struct ATS_Address *aa = NULL;
2155 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len + strlen (plugin_name) + 1);
2156 aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
2157 aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
2158 aa->atsi[0].value = htonl (network);
2162 aa->addr_len = plugin_addr_len;
2164 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2165 GNUNET_memcpy (&aa[1], plugin_addr, plugin_addr_len);
2166 GNUNET_memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2167 aa->session_id = session_id;
2175 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2178 struct TestAddress *a;
2181 if (NULL == (p = find_peer_by_id (op->peer_id)))
2183 p = GNUNET_new (struct TestPeer);
2184 p->id = op->peer_id;
2185 p->assigned_bw_in = 0;
2186 p->assigned_bw_out = 0;
2187 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2188 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2190 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2191 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2194 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2197 if (NULL != (find_address_by_id (p, op->address_id)))
2199 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2200 op->address_id, op->peer_id);
2204 a = GNUNET_new (struct TestAddress);
2205 a->aid = op->address_id;
2206 a->network = op->address_network;
2207 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2208 strlen (op->address) + 1, op->address_session, op->address_network);
2209 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2210 GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
2212 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2213 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2215 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2216 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2218 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding address %u for peer %u in network `%s'\n",
2219 op->address_id, op->peer_id, GNUNET_NT_to_string(a->network));
2221 sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
2227 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2230 struct TestAddress *a;
2231 struct PropertyGenerator *pg;
2233 if (NULL == (p = find_peer_by_id (op->peer_id)))
2236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2237 "Deleting address for unknown peer %u\n", op->peer_id);
2241 if (NULL == (a =find_address_by_id (p, op->address_id)))
2244 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2245 "Deleting address for unknown peer %u\n", op->peer_id);
2249 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2251 GNUNET_ATS_solver_generate_property_stop (pg);
2254 GNUNET_assert (GNUNET_YES ==
2255 GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
2258 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2259 "Removing address %u for peer %u\n",
2263 sh->sf->s_del (sh->sf->cls, a->ats_addr);
2267 GNUNET_ATS_solver_logging_now (l);
2269 GNUNET_CONTAINER_DLL_remove(p->addr_head, p->addr_tail, a);
2271 GNUNET_free_non_null(a->ats_addr->atsi);
2272 GNUNET_free (a->ats_addr);
2278 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2280 struct PropertyGenerator *pg;
2282 struct TestAddress *a;
2284 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2286 GNUNET_ATS_solver_generate_property_stop (pg);
2290 if (NULL == (p = find_peer_by_id (op->peer_id)))
2293 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2294 "Starting property generation for unknown peer %u\n", op->peer_id);
2298 if (NULL == (a = find_address_by_id (p, op->address_id)))
2301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2302 "Setting property for unknown address %u\n", op->peer_id);
2306 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2318 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2320 struct PropertyGenerator *pg = find_prop_gen(op->peer_id, op->address_id,
2324 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2325 "Stopping preference generation for peer %u address %u\n", op->peer_id,
2327 GNUNET_ATS_solver_generate_property_stop (pg);
2331 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2332 "Cannot find preference generator for peer %u address %u\n",
2333 op->peer_id, op->address_id);
2339 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2341 struct PreferenceGenerator *pg;
2342 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2344 GNUNET_ATS_solver_generate_preferences_stop (pg);
2348 if (NULL == (find_peer_by_id (op->peer_id)))
2351 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2352 "Starting preference generation for unknown peer %u\n", op->peer_id);
2356 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2369 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2371 struct PreferenceGenerator *pg = find_pref_gen(op->peer_id,
2375 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2376 "Stopping property generation for peer %u address %u\n", op->peer_id,
2378 GNUNET_ATS_solver_generate_preferences_stop (pg);
2382 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2383 "Cannot find preference generator for peer %u address %u\n",
2384 op->peer_id, op->address_id);
2391 enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2395 if (NULL == (p = find_peer_by_id (op->peer_id)))
2398 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2399 "Requesting address for unknown peer %u\n", op->peer_id);
2403 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2405 p->is_requested = GNUNET_YES;
2407 sh->sf->s_get (sh->sf->cls, &p->peer_id);
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);
2424 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2425 "Stop requesting address for peer %u\n",
2427 p->is_requested = GNUNET_NO;
2428 p->assigned_bw_in = 0;
2429 p->assigned_bw_out = 0;
2430 sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
2434 GNUNET_ATS_solver_logging_now (l);
2439 static void enforce_episode (struct Episode *ep)
2441 struct GNUNET_ATS_TEST_Operation *cur;
2442 for (cur = ep->head; NULL != cur; cur = cur->next)
2444 switch (cur->type) {
2445 case SOLVER_OP_ADD_ADDRESS:
2446 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2447 print_op (cur->type), cur->peer_id, cur->address_id);
2448 enforce_add_address (cur);
2450 case SOLVER_OP_DEL_ADDRESS:
2451 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2452 print_op (cur->type), cur->peer_id, cur->address_id);
2453 enforce_del_address (cur);
2455 case SOLVER_OP_START_SET_PROPERTY:
2456 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2457 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2458 enforce_start_property (cur);
2460 case SOLVER_OP_STOP_SET_PROPERTY:
2461 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2462 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2463 enforce_stop_property (cur);
2465 case SOLVER_OP_START_SET_PREFERENCE:
2466 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2467 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2468 enforce_start_preference (cur);
2470 case SOLVER_OP_STOP_SET_PREFERENCE:
2471 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2472 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2473 enforce_stop_preference (cur);
2475 case SOLVER_OP_START_REQUEST:
2476 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2477 print_op (cur->type), cur->peer_id);
2478 enforce_start_request (cur);
2480 case SOLVER_OP_STOP_REQUEST:
2481 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2482 print_op (cur->type), cur->peer_id);
2483 enforce_stop_request (cur);
2493 timeout_episode (void *cls)
2495 struct Experiment *e = cls;
2497 e->episode_timeout_task = NULL;
2498 if (NULL != e->ep_done_cb)
2499 e->ep_done_cb (e->cur);
2501 /* Scheduling next */
2502 e->cur = e->cur->next;
2506 fprintf (stderr, "Last episode done!\n");
2507 if (NULL != e->experiment_timeout_task)
2509 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2510 e->experiment_timeout_task = NULL;
2512 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
2516 fprintf (stderr, "Running episode %u with timeout %s\n",
2518 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2519 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2520 &timeout_episode, e);
2521 enforce_episode(e->cur);
2528 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2529 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
2530 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
2532 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2533 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
2534 e->e_done_cb = e_done_cb;
2535 e->ep_done_cb = ep_done_cb;
2536 e->start_time = GNUNET_TIME_absolute_get();
2538 /* Start total time out */
2539 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2540 &timeout_experiment, e);
2543 if (NULL == e->start)
2550 fprintf (stderr, "Running episode %u with timeout %s\n",
2552 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2553 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2554 &timeout_episode, e);
2555 enforce_episode(e->cur);
2560 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2562 if (NULL != e->experiment_timeout_task)
2564 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2565 e->experiment_timeout_task = NULL;
2567 if (NULL != e->episode_timeout_task)
2569 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2570 e->episode_timeout_task = NULL;
2574 GNUNET_CONFIGURATION_destroy(e->cfg);
2577 free_experiment (e);
2582 GNUNET_ATS_solvers_experimentation_load (char *filename)
2584 struct Experiment *e;
2585 struct GNUNET_CONFIGURATION_Handle *cfg;
2588 cfg = GNUNET_CONFIGURATION_create();
2589 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2591 fprintf (stderr, "Failed to load `%s'\n", filename);
2592 GNUNET_CONFIGURATION_destroy (cfg);
2596 e = create_experiment ();
2598 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2601 fprintf (stderr, "Invalid %s \n", "name");
2602 free_experiment (e);
2606 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2608 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2609 "log_prefix", &e->log_prefix))
2611 fprintf (stderr, "Invalid %s \n", "log_prefix");
2612 free_experiment (e);
2616 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2619 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2620 "log_output_dir", &e->log_output_dir))
2622 e->log_output_dir = NULL;
2625 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging output directory: `%s'\n",
2629 if (GNUNET_SYSERR == (e->log_append_time_stamp = GNUNET_CONFIGURATION_get_value_yesno(cfg,
2630 "experiment", "log_append_time_stamp")))
2631 e->log_append_time_stamp = GNUNET_YES;
2632 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging append timestamp: `%s'\n",
2633 (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
2636 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2637 "cfg_file", &e->cfg_file))
2639 fprintf (stderr, "Invalid %s \n", "cfg_file");
2640 free_experiment (e);
2645 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n", e->cfg_file);
2646 e->cfg = GNUNET_CONFIGURATION_create();
2647 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2649 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2650 free_experiment (e);
2656 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2657 "log_freq", &e->log_freq))
2659 fprintf (stderr, "Invalid %s \n", "log_freq");
2660 free_experiment (e);
2664 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2665 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
2667 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2668 "max_duration", &e->max_duration))
2670 fprintf (stderr, "Invalid %s", "max_duration");
2671 free_experiment (e);
2675 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2676 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
2678 if (GNUNET_SYSERR == load_episodes (e, cfg))
2680 GNUNET_ATS_solvers_experimentation_stop (e);
2681 GNUNET_CONFIGURATION_destroy (cfg);
2683 fprintf (stderr, "Failed to load experiment\n");
2686 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded %u episodes with total duration %s\n",
2688 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
2690 GNUNET_CONFIGURATION_destroy (cfg);
2701 free_all_it (void *cls,
2702 const struct GNUNET_PeerIdentity *key,
2705 struct ATS_Address *address = value;
2706 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (sh->env.addresses,
2708 GNUNET_free (address);
2714 GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2716 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2718 GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
2720 GAS_normalization_stop();
2722 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
2725 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
2726 GNUNET_free (sh->plugin);
2732 * Load quotas for networks from configuration
2734 * @param cfg configuration handle
2735 * @param out_dest where to write outbound quotas
2736 * @param in_dest where to write inbound quotas
2737 * @param dest_length length of inbound and outbound arrays
2738 * @return number of networks loaded
2741 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2742 unsigned long long *out_dest,
2743 unsigned long long *in_dest,
2746 char * entry_in = NULL;
2747 char * entry_out = NULL;
2748 char * quota_out_str;
2749 char * quota_in_str;
2753 for (c = 0; (c < GNUNET_NT_COUNT) && (c < dest_length); c++)
2757 GNUNET_asprintf (&entry_out,
2759 GNUNET_NT_to_string (c));
2760 GNUNET_asprintf (&entry_in,
2762 GNUNET_NT_to_string (c));
2765 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
2768 if (0 == strcmp(quota_out_str, BIG_M_STRING))
2770 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2773 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
2775 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
2778 if (GNUNET_NO == res)
2780 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2781 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2782 GNUNET_NT_to_string (c),
2784 GNUNET_ATS_DefaultBandwidth);
2785 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2789 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2790 "Outbound quota configure for network `%s' is %llu\n",
2791 GNUNET_NT_to_string (c),
2794 GNUNET_free (quota_out_str);
2798 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2799 _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
2800 GNUNET_NT_to_string (c),
2801 GNUNET_ATS_DefaultBandwidth);
2802 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2806 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
2809 if (0 == strcmp(quota_in_str, BIG_M_STRING))
2811 in_dest[c] = GNUNET_ATS_MaxBandwidth;
2814 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
2816 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
2819 if (GNUNET_NO == res)
2821 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2822 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2823 GNUNET_NT_to_string (c),
2825 GNUNET_ATS_DefaultBandwidth);
2826 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
2830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2831 "Inbound quota configured for network `%s' is %llu\n",
2832 GNUNET_NT_to_string (c),
2835 GNUNET_free (quota_in_str);
2839 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2840 _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
2841 GNUNET_NT_to_string (c),
2842 GNUNET_ATS_DefaultBandwidth);
2843 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2845 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2846 "Loaded quota for network `%s' (in/out): %llu %llu\n",
2847 GNUNET_NT_to_string (c),
2850 GNUNET_free (entry_out);
2851 GNUNET_free (entry_in);
2853 return GNUNET_NT_COUNT;
2858 * Information callback for the solver
2860 * @param cls the closure
2861 * @param op the solver operation
2862 * @param stat status of the solver operation
2863 * @param add additional solver information
2866 solver_info_cb (void *cls,
2867 enum GAS_Solver_Operation op,
2868 enum GAS_Solver_Status stat,
2869 enum GAS_Solver_Additional_Information add)
2874 add_info = "GAS_INFO_NONE";
2877 add_info = "GAS_INFO_MLP_FULL";
2879 case GAS_INFO_UPDATED:
2880 add_info = "GAS_INFO_MLP_UPDATED";
2882 case GAS_INFO_PROP_ALL:
2883 add_info = "GAS_INFO_PROP_ALL";
2885 case GAS_INFO_PROP_SINGLE:
2886 add_info = "GAS_INFO_PROP_SINGLE";
2889 add_info = "INVALID";
2895 case GAS_OP_SOLVE_START:
2896 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2897 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
2898 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2900 case GAS_OP_SOLVE_STOP:
2901 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2902 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
2903 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2906 case GAS_OP_SOLVE_SETUP_START:
2907 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2908 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
2909 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2912 case GAS_OP_SOLVE_SETUP_STOP:
2913 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2914 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
2915 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2918 case GAS_OP_SOLVE_MLP_LP_START:
2919 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2920 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
2921 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2923 case GAS_OP_SOLVE_MLP_LP_STOP:
2924 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2925 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
2926 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2929 case GAS_OP_SOLVE_MLP_MLP_START:
2930 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2931 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
2932 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2934 case GAS_OP_SOLVE_MLP_MLP_STOP:
2935 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2936 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
2937 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2939 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
2940 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2941 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
2942 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2944 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
2945 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2946 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
2947 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2955 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
2957 struct GNUNET_TIME_Relative duration;
2959 static struct PreferenceGenerator *pg;
2961 if ( (0 == address->assigned_bw_out) && (0 == address->assigned_bw_in) )
2963 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2964 "Solver notified to disconnect peer `%s'\n",
2965 GNUNET_i2s (&address->peer));
2967 p = find_peer_by_pid(&address->peer);
2970 p->assigned_bw_out = address->assigned_bw_out;
2971 p->assigned_bw_in = address->assigned_bw_in;
2973 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
2975 if (pg->peer == p->id)
2977 duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_bw_update);
2978 delta = duration.rel_value_us * pg->last_assigned_bw_out;
2979 pg->feedback_bw_out_acc += delta;
2981 delta = duration.rel_value_us * pg->last_assigned_bw_in;
2982 pg->feedback_bw_in_acc += delta;
2984 pg->last_assigned_bw_in = address->assigned_bw_in;
2985 pg->last_assigned_bw_out = address->assigned_bw_out;
2986 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
2990 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2991 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
2992 GNUNET_i2s (&address->peer),
2994 address->assigned_bw_out,
2995 address->assigned_bw_in);
2998 GNUNET_ATS_solver_logging_now (l);
3004 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3007 if (GNUNET_YES == opt_disable_normalization)
3009 if (NULL == (p = find_peer_by_pid (id)))
3014 return GAS_preference_get_by_peer (NULL,
3019 struct SolverHandle *
3020 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3022 struct SolverHandle *sh;
3026 case GNUNET_ATS_SOLVER_PROPORTIONAL:
3027 solver_str = "proportional";
3029 case GNUNET_ATS_SOLVER_MLP:
3032 case GNUNET_ATS_SOLVER_RIL:
3041 sh = GNUNET_new (struct SolverHandle);
3042 GNUNET_asprintf (&sh->plugin,
3043 "libgnunet_plugin_ats_%s",
3045 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
3047 /* setup environment */
3048 sh->env.cfg = e->cfg;
3049 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
3050 sh->env.addresses = sh->addresses;
3051 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
3052 sh->env.get_preferences = &get_preferences_cb;
3053 sh->env.network_count = GNUNET_NT_COUNT;
3054 sh->env.info_cb = &solver_info_cb;
3055 sh->env.network_count = GNUNET_NT_COUNT;
3057 /* start normalization */
3058 GAS_normalization_start ();
3061 if (GNUNET_NT_COUNT != GNUNET_ATS_solvers_load_quotas (e->cfg,
3062 sh->env.out_quota, sh->env.in_quota, GNUNET_NT_COUNT))
3065 GNUNET_free (sh->plugin);
3071 sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
3074 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
3076 GNUNET_free (sh->plugin);
3088 struct TestPeer *cur;
3089 struct TestPeer *next;
3091 struct TestAddress *cur_a;
3092 struct TestAddress *next_a;
3095 GNUNET_ATS_solver_logging_stop (l);
3097 /* Stop all preference generation */
3098 GNUNET_ATS_solver_generate_preferences_stop_all ();
3100 /* Stop all property generation */
3101 GNUNET_ATS_solver_generate_property_stop_all ();
3105 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
3106 GNUNET_ATS_solver_logging_eval (l);
3110 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
3111 GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
3117 GNUNET_ATS_solver_logging_free (l);
3121 /* Clean up experiment */
3124 GNUNET_ATS_solvers_experimentation_stop (e);
3129 while (NULL != (cur = next))
3132 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3133 next_a = cur->addr_head;
3134 while (NULL != (cur_a = next_a))
3136 next_a = cur_a->next;
3137 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3138 GNUNET_free (cur_a);
3144 GNUNET_ATS_solvers_solver_stop (sh);
3153 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
3155 if (GNUNET_OK == success)
3156 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3157 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3159 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3161 GNUNET_SCHEDULER_add_now (&done, NULL);
3165 episode_done_cb (struct Episode *ep)
3167 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3180 GNUNET_ATS_solvers_experimentation_stop (e);
3185 GNUNET_ATS_solvers_solver_stop (sh);
3191 run (void *cls, char * const *args, const char *cfgfile,
3192 const struct GNUNET_CONFIGURATION_Handle *cfg)
3194 enum GNUNET_ATS_Solvers solver;
3197 if (NULL == opt_exp_file)
3199 fprintf (stderr, "No experiment given ...\n");
3205 if (NULL == opt_solver)
3207 fprintf (stderr, "No solver given ...\n");
3213 if (0 == strcmp(opt_solver, "mlp"))
3215 solver = GNUNET_ATS_SOLVER_MLP;
3217 else if (0 == strcmp(opt_solver, "proportional"))
3219 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3221 else if (0 == strcmp(opt_solver, "ril"))
3223 solver = GNUNET_ATS_SOLVER_RIL;
3227 fprintf (stderr, "No solver given ...");
3233 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3234 default_properties[c] = DEFAULT_REL_QUALITY;
3236 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3237 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3239 /* load experiment */
3240 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3241 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3244 fprintf (stderr, "Failed to load experiment ...\n");
3251 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3252 sh = GNUNET_ATS_solvers_solver_start (solver);
3255 fprintf (stderr, "Failed to start solver ...\n");
3262 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3263 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3265 /* run experiment */
3266 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3267 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3268 experiment_done_cb);
3275 * Main function of the benchmark
3277 * @param argc argument count
3278 * @param argv argument values
3281 main (int argc, char *argv[])
3283 opt_exp_file = NULL;
3285 opt_log = GNUNET_NO;
3286 opt_save = GNUNET_NO;
3290 static struct GNUNET_GETOPT_CommandLineOption options[] =
3292 GNUNET_GETOPT_option_string ('s',
3294 gettext_noop ("solver to use"),
3297 GNUNET_GETOPT_option_string ('e',
3299 gettext_noop ("experiment to use"),
3302 GNUNET_GETOPT_option_verbose (&opt_verbose),
3304 GNUNET_GETOPT_option_flag ('p',
3306 gettext_noop ("print logging"),
3309 GNUNET_GETOPT_option_flag ('f',
3311 gettext_noop ("save logging to disk"),
3314 GNUNET_GETOPT_option_flag ('d',
3316 gettext_noop ("disable normalization"),
3317 &opt_disable_normalization),
3319 GNUNET_GETOPT_OPTION_END
3322 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3323 NULL, options, &run, argv[0]);
3327 /* end of file ats-testing-experiment.c*/