2 This file is part of GNUnet.
3 (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"
30 #define BIG_M_STRING "unlimited"
32 static struct Experiment *e;
34 static struct LoggingHandle *l;
36 static struct SolverHandle *sh;
38 static struct TestPeer *peer_head;
39 static struct TestPeer *peer_tail;
41 static double default_properties[GNUNET_ATS_PropertyCount];
42 static double default_preferences[GNUNET_ATS_PreferenceCount];
45 * cmd option -e: experiment file
47 static char *opt_exp_file;
49 static char *opt_solver;
52 * cmd option -l: enable logging
57 * cmd option -p: enable plots
62 * cmd option -v: verbose logs
64 static int opt_verbose;
67 * cmd option -p: print logs
72 * cmd option -d: disable normalization
74 static int opt_disable_normalization;
82 print_generator_type (enum GeneratorType g)
85 case GNUNET_ATS_TEST_TG_CONSTANT:
87 case GNUNET_ATS_TEST_TG_LINEAR:
89 case GNUNET_ATS_TEST_TG_RANDOM:
91 case GNUNET_ATS_TEST_TG_SINUS:
99 struct AddressLookupCtx
101 struct ATS_Address *res;
107 int find_address_it (void *cls,
108 const struct GNUNET_PeerIdentity *key,
111 struct AddressLookupCtx *ctx = cls;
112 struct ATS_Address *addr = value;
114 if ( (0 == strcmp (ctx->plugin, addr->plugin)) &&
115 (0 == strcmp (ctx->addr, addr->addr)) )
123 static struct TestPeer *
124 find_peer_by_id (int id)
126 struct TestPeer *cur;
127 for (cur = peer_head; NULL != cur; cur = cur->next)
133 static struct TestPeer *
134 find_peer_by_pid (const struct GNUNET_PeerIdentity *pid)
136 struct TestPeer *cur;
137 for (cur = peer_head; NULL != cur; cur = cur->next)
138 if (0 == memcmp (&cur->peer_id, pid, sizeof (struct GNUNET_PeerIdentity)))
143 static struct TestAddress *
144 find_address_by_id (struct TestPeer *peer, int aid)
146 struct TestAddress *cur;
147 for (cur = peer->addr_head; NULL != cur; cur = cur->next)
154 static struct TestAddress *
155 find_address_by_ats_address (struct TestPeer *p, const struct ATS_Address *addr)
157 struct TestAddress *cur;
158 for (cur = p->addr_head; NULL != cur; cur = cur->next)
159 if ((0 == strcmp(cur->ats_addr->plugin, addr->plugin)) &&
160 (cur->ats_addr->addr_len == addr->addr_len) &&
161 (0 == memcmp (cur->ats_addr->addr, addr->addr, addr->addr_len)))
172 GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
174 struct LoggingTimeStep *lts;
175 struct TestPeer *cur;
176 struct TestAddress *cur_addr;
177 struct LoggingPeer *log_p;
178 struct LoggingAddress *log_a;
181 lts = GNUNET_new (struct LoggingTimeStep);
182 GNUNET_CONTAINER_DLL_insert_tail(l->head, l->tail, lts);
183 lts->timestamp = GNUNET_TIME_absolute_get();
184 if (NULL == lts->prev)
185 lts->delta = GNUNET_TIME_UNIT_ZERO;
187 lts->delta = GNUNET_TIME_absolute_get_duration(lts->prev->timestamp);
189 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging %llu, delta %llu\n",
190 lts->timestamp.abs_value_us, lts->delta.rel_value_us);
193 /* Store logging data here */
194 for (cur = peer_head; NULL != cur; cur = cur->next)
196 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %u\n", cur->peer_id);
198 log_p = GNUNET_new (struct LoggingPeer);
200 log_p->peer_id = cur->peer_id;
201 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
203 log_p->pref_abs[c] = cur->pref_abs[c];
204 log_p->pref_norm[c] = cur->pref_norm[c];
205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n",
206 GNUNET_ATS_print_preference_type(c),
207 log_p->pref_abs[c], log_p->pref_norm[c]);
209 GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p);
211 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
213 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %u address %u\n", cur->peer_id, cur_addr->aid);
214 log_a = GNUNET_new (struct LoggingAddress);
215 log_a->aid = cur_addr->aid;
216 log_a->active = cur_addr->ats_addr->active;
217 log_a->network = cur_addr->network;
218 log_a->used = cur_addr->ats_addr->used;
219 log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
220 log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
221 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
223 log_a->prop_abs[c] = cur_addr->prop_abs[c];
224 log_a->prop_norm[c] = cur_addr->prop_norm[c];
225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n",
226 GNUNET_ATS_print_property_type(c),
227 log_a->prop_abs[c], log_a->prop_norm[c]);
229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", ntohl(log_a->assigned_bw_in.value__));
231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW out = %llu\n", ntohl(log_a->assigned_bw_out.value__));
233 GNUNET_CONTAINER_DLL_insert_tail(log_p->addr_head, log_p->addr_tail, log_a);
239 logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
241 struct LoggingHandle *l = cls;
242 l->logging_task = GNUNET_SCHEDULER_NO_TASK;
244 GNUNET_ATS_solver_logging_now (l);
246 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq, &logging_task, l);
250 struct LoggingHandle *
251 GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
253 struct LoggingHandle *l;
254 l = GNUNET_new (struct LoggingHandle);
256 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
257 GNUNET_STRINGS_relative_time_to_string(freq, GNUNET_NO));
259 l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
264 GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
266 if (GNUNET_SCHEDULER_NO_TASK != l->logging_task)
267 GNUNET_SCHEDULER_cancel (l->logging_task);
269 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
271 l->logging_task = GNUNET_SCHEDULER_NO_TASK;
274 static struct LoggingFileHandle *
275 find_logging_file_handle (struct LoggingFileHandle *lf_head,
276 struct LoggingFileHandle *lf_tail,
277 int peer_id, int address_id)
279 struct LoggingFileHandle *res;
281 for (res = lf_head; NULL != res; res = res->next)
282 if ((res->pid == peer_id) && (res->pid == address_id))
289 GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l)
291 struct LoggingTimeStep *lts;
292 struct LoggingPeer *log_p;
293 struct LoggingAddress *log_a;
294 struct LoggingFileHandle *lf_head;
295 struct LoggingFileHandle *lf_tail;
296 struct LoggingFileHandle *cur;
297 struct LoggingFileHandle *next;
301 char * propstring_tmp;
303 char * prefstring_tmp;
310 for (lts = l->head; NULL != lts; lts = lts->next)
313 fprintf (stderr, "Writing log step %llu\n",
314 (long long unsigned int) lts->timestamp.abs_value_us);
316 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
318 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
321 cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
325 cur = GNUNET_new (struct LoggingFileHandle);
326 cur->aid = log_a->aid;
327 cur->pid = log_p->id;
329 GNUNET_asprintf (&filename, "%s_%s_%u_%u_%llu.log", e->log_prefix, opt_solver,
330 cur->aid, cur->pid, l->head->timestamp.abs_value_us);
332 fprintf (stderr, "Add writing log data for %i %i to file `%s'\n",
333 cur->pid, cur->aid, filename);
336 cur->f_hd = GNUNET_DISK_file_open (filename,
337 GNUNET_DISK_OPEN_READWRITE |
338 GNUNET_DISK_OPEN_CREATE |
339 GNUNET_DISK_OPEN_TRUNCATE,
340 GNUNET_DISK_PERM_USER_READ |
341 GNUNET_DISK_PERM_USER_WRITE |
342 GNUNET_DISK_PERM_GROUP_READ |
343 GNUNET_DISK_PERM_OTHER_READ);
344 if (NULL == cur->f_hd)
346 fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
347 GNUNET_free (filename);
350 GNUNET_free (filename);
351 GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
353 GNUNET_asprintf(&datastring,"#timestamp_abs; addr net; addr_active; bw in; bw out; " \
354 "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
355 "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;"\
357 "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
358 "COST_WLAN; COST_WLAN; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n",
359 lts->timestamp.abs_value_us,
361 ntohl (log_a->assigned_bw_in.value__),
362 ntohl (log_a->assigned_bw_out.value__));
363 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen(datastring));
364 GNUNET_free (datastring);
368 prefstring = GNUNET_strdup("");
369 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
372 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
373 GNUNET_ATS_print_preference_type(c),
374 log_p->pref_abs[c], log_p->pref_norm[c]);
376 GNUNET_asprintf(&prefstring_tmp,"%s|%.3f|%.3f",
377 prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
380 GNUNET_free (prefstring);
381 prefstring = GNUNET_strdup(prefstring_tmp);
382 GNUNET_free (prefstring_tmp);
386 propstring = GNUNET_strdup("");
387 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
389 if (GNUNET_ATS_NETWORK_TYPE == c)
392 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
393 GNUNET_ATS_print_property_type(c),
394 log_a->prop_abs[c], log_a->prop_norm[c]);*/
395 GNUNET_asprintf(&propstring_tmp,"%s;%.3f;%.3f",
396 propstring, log_a->prop_abs[c], log_a->prop_norm[c]);
397 GNUNET_free (propstring);
398 propstring = GNUNET_strdup(propstring_tmp);
399 GNUNET_free (propstring_tmp);
402 GNUNET_asprintf(&datastring,"%llu;%u;%i;%u;%u;%s;%s\n",
403 lts->timestamp.abs_value_us,
406 ntohl (log_a->assigned_bw_in.value__),
407 ntohl (log_a->assigned_bw_out.value__),
408 propstring, prefstring);
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 %u\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 %u address %u: %u %u %u\n",
458 log_p->id, log_a->aid, log_a->active,
459 ntohl(log_a->assigned_bw_in.value__),
460 ntohl(log_a->assigned_bw_out.value__));
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 (GNUNET_SCHEDULER_NO_TASK != l->logging_task)
486 GNUNET_SCHEDULER_cancel (l->logging_task);
487 l->logging_task = GNUNET_SCHEDULER_NO_TASK;
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;
593 pg->set_task = GNUNET_SCHEDULER_NO_TASK;
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)))
606 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
607 "Setting property generation for unknown peer %u\n",
610 if (NULL == (a = find_address_by_id (p, pg->address_id)))
612 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
613 "Setting property generation for unknown peer %u\n",
617 prop_value = get_property (pg);
618 a->prop_abs[pg->ats_property] = prop_value;
620 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
621 "Setting property for peer [%u] address [%u] for %s to %f\n",
622 pg->peer, pg->address_id,
623 GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
625 atsi.type = htonl (pg->ats_property);
626 atsi.value = htonl ((uint32_t) prop_value);
628 /* set performance here! */
629 sh->env.sf.s_bulk_start (sh->solver);
630 if (GNUNET_YES == opt_disable_normalization)
632 a->prop_abs[pg->ats_property] = prop_value;
633 a->prop_norm[pg->ats_property] = prop_value;
634 sh->env.sf.s_address_update_property (sh->solver, a->ats_addr,
635 pg->ats_property, prop_value, prop_value);
638 GAS_normalization_normalize_property (sh->addresses,
639 pg->test_address->ats_addr, &atsi, 1);
640 sh->env.sf.s_bulk_stop (sh->solver);
642 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
648 * Set ats_property to 0 to find all pgs
651 static struct PropertyGenerator *
652 find_prop_gen (unsigned int peer, unsigned int address,
653 uint32_t ats_property)
655 struct PropertyGenerator *cur;
656 for (cur = prop_gen_head; NULL != cur; cur = cur->next)
657 if ((cur->peer == peer) && (cur->address_id == address))
659 if ((cur->ats_property == ats_property) || (0 == ats_property))
666 GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
668 GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
670 if (GNUNET_SCHEDULER_NO_TASK != pg->set_task)
672 GNUNET_SCHEDULER_cancel (pg->set_task);
673 pg->set_task = GNUNET_SCHEDULER_NO_TASK;
675 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
676 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
677 pg->peer, pg->address_id,
678 GNUNET_ATS_print_property_type(pg->ats_property));
685 * Generate between the source master and the partner and set property with a
686 * value depending on the generator.
689 * @param address_id partner
690 * @param test_peer the peer
691 * @param test_address the address
692 * @param type type of generator
693 * @param base_value base value
694 * @param value_rate maximum value
695 * @param period duration of a period of generation (~ 1/frequency)
696 * @param frequency how long to generate property
697 * @param ats_property ATS property to generate
698 * @return the property generator
700 struct PropertyGenerator *
701 GNUNET_ATS_solver_generate_property_start (unsigned int peer,
702 unsigned int address_id,
703 struct TestPeer *test_peer,
704 struct TestAddress *test_address,
705 enum GeneratorType type,
708 struct GNUNET_TIME_Relative period,
709 struct GNUNET_TIME_Relative frequency,
710 uint32_t ats_property)
712 struct PropertyGenerator *pg;
714 pg = GNUNET_new (struct PropertyGenerator);
715 GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
718 pg->test_address = test_address;
719 pg->test_peer = test_peer;
720 pg->address_id = address_id;
721 pg->ats_property = ats_property;
722 pg->base_value = base_value;
723 pg->max_value = value_rate;
724 pg->duration_period = period;
725 pg->frequency = frequency;
726 pg->time_start = GNUNET_TIME_absolute_get();
729 case GNUNET_ATS_TEST_TG_CONSTANT:
730 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
731 "Setting up %s property generator peer [%u] address [%u] `%s'"\
733 print_generator_type(type), pg->peer, pg->address_id,
734 GNUNET_ATS_print_property_type (ats_property),
737 case GNUNET_ATS_TEST_TG_LINEAR:
738 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
739 "Setting up %s property generator peer [%u] address [%u] `%s' " \
740 "min %u Bips max %u Bips\n",
741 print_generator_type(type), pg->peer, pg->address_id,
742 GNUNET_ATS_print_property_type(ats_property),
743 base_value, value_rate);
745 case GNUNET_ATS_TEST_TG_SINUS:
746 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
747 "Setting up %s property generator peer [%u] address [%u] `%s' "\
748 "baserate %u Bips, amplitude %u Bps\n",
749 print_generator_type(type), pg->peer, pg->address_id,
750 GNUNET_ATS_print_property_type(ats_property),
751 base_value, value_rate);
753 case GNUNET_ATS_TEST_TG_RANDOM:
754 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
755 "Setting up %s property generator peer [%u] address [%u] `%s' "\
756 "min %u Bips max %u Bps\n",
757 print_generator_type(type), pg->peer, pg->address_id,
758 GNUNET_ATS_print_property_type(ats_property),
759 base_value, value_rate);
765 pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
772 * Stop all preferences generators
775 GNUNET_ATS_solver_generate_property_stop_all ()
777 struct PropertyGenerator *cur;
778 struct PropertyGenerator *next;
779 next = prop_gen_head;
780 for (cur = next; NULL != cur; cur = next)
783 GNUNET_ATS_solver_generate_property_stop (cur);
789 * Preference Generators
792 static struct PreferenceGenerator *pref_gen_head;
793 static struct PreferenceGenerator *pref_gen_tail;
796 get_preference (struct PreferenceGenerator *pg)
798 struct GNUNET_TIME_Relative time_delta;
802 /* Calculate the current preference value */
804 case GNUNET_ATS_TEST_TG_CONSTANT:
805 pref_value = pg->base_value;
807 case GNUNET_ATS_TEST_TG_LINEAR:
808 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
809 /* Calculate point of time in the current period */
810 time_delta.rel_value_us = time_delta.rel_value_us %
811 pg->duration_period.rel_value_us;
812 delta_value = ((double) time_delta.rel_value_us /
813 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
814 if ((pg->max_value < pg->base_value) &&
815 ((pg->max_value - pg->base_value) > pg->base_value))
817 /* This will cause an underflow */
820 pref_value = pg->base_value + delta_value;
822 case GNUNET_ATS_TEST_TG_RANDOM:
823 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
824 10000 * (pg->max_value - pg->base_value)) / 10000;
825 pref_value = pg->base_value + delta_value;
827 case GNUNET_ATS_TEST_TG_SINUS:
828 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
829 /* Calculate point of time in the current period */
830 time_delta.rel_value_us = time_delta.rel_value_us %
831 pg->duration_period.rel_value_us;
832 if ((pg->max_value - pg->base_value) > pg->base_value)
834 /* This will cause an underflow for second half of sinus period,
835 * will be detected in general when experiments are loaded */
838 delta_value = (pg->max_value - pg->base_value) *
839 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
840 time_delta.rel_value_us);
841 pref_value = pg->base_value + delta_value;
847 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
854 set_pref_task (void *cls,
855 const struct GNUNET_SCHEDULER_TaskContext *tc)
857 struct PreferenceGenerator *pg = cls;
860 pg->set_task = GNUNET_SCHEDULER_NO_TASK;
862 if (NULL == (p = find_peer_by_id (pg->peer)))
865 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
866 "Setting preference for unknown peer %u\n", pg->peer);
870 pref_value = get_preference (pg);
871 p->pref_abs[pg->kind] = pref_value;
873 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
874 "Setting preference for peer [%u] for client %p pref %s to %f\n",
875 pg->peer, NULL + (pg->client_id),
876 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
878 sh->env.sf.s_bulk_start (sh->solver);
879 if (GNUNET_YES == opt_disable_normalization)
881 p->pref_abs[pg->kind] = pref_value;
882 p->pref_norm[pg->kind] = pref_value;
883 sh->env.sf.s_pref (sh->solver, &p->peer_id, pg->kind, pref_value);
886 GAS_normalization_normalize_preference (NULL + (pg->client_id),
887 &p->peer_id, pg->kind, pref_value);
888 sh->env.sf.s_bulk_stop (sh->solver);
891 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
892 //p->pref_bandwidth = pref_value;
894 case GNUNET_ATS_PREFERENCE_LATENCY:
895 //p->pref_delay = pref_value;
901 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
906 static struct PreferenceGenerator *
907 find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
909 struct PreferenceGenerator *cur;
910 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
911 if (cur->peer == peer)
913 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
920 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
922 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
924 if (GNUNET_SCHEDULER_NO_TASK != pg->set_task)
926 GNUNET_SCHEDULER_cancel (pg->set_task);
927 pg->set_task = GNUNET_SCHEDULER_NO_TASK;
929 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
930 "Removing old up preference generator peer [%u] `%s'\n",
931 pg->peer, GNUNET_ATS_print_preference_type(pg->kind));
938 * Generate between the source master and the partner and set property with a
939 * value depending on the generator.
942 * @param address_id partner
943 * @param client_id the client
944 * @param type type of generator
945 * @param base_value base value
946 * @param value_rate maximum value
947 * @param period duration of a period of generation (~ 1/frequency)
948 * @param frequency how long to generate property
949 * @param kind ATS preference to generate
950 * @return the preference generator
952 struct PreferenceGenerator *
953 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
954 unsigned int address_id,
955 unsigned int client_id,
956 enum GeneratorType type,
959 struct GNUNET_TIME_Relative period,
960 struct GNUNET_TIME_Relative frequency,
961 enum GNUNET_ATS_PreferenceKind kind)
963 struct PreferenceGenerator *pg;
965 pg = GNUNET_new (struct PreferenceGenerator);
966 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
969 pg->client_id = client_id;
971 pg->base_value = base_value;
972 pg->max_value = value_rate;
973 pg->duration_period = period;
974 pg->frequency = frequency;
975 pg->time_start = GNUNET_TIME_absolute_get();
978 case GNUNET_ATS_TEST_TG_CONSTANT:
979 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
980 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
981 print_generator_type (type), pg->peer,
982 GNUNET_ATS_print_preference_type(kind),
985 case GNUNET_ATS_TEST_TG_LINEAR:
986 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
987 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
988 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
989 base_value, value_rate);
991 case GNUNET_ATS_TEST_TG_SINUS:
992 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
993 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
994 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
995 base_value, value_rate);
997 case GNUNET_ATS_TEST_TG_RANDOM:
998 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
999 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1000 print_generator_type (type), pg->peer, GNUNET_ATS_print_preference_type(kind),
1001 base_value, value_rate);
1007 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1014 * Stop all preferences generators
1017 GNUNET_ATS_solver_generate_preferences_stop_all ()
1019 struct PreferenceGenerator *cur;
1020 struct PreferenceGenerator *next;
1021 next = pref_gen_head;
1022 for (cur = next; NULL != cur; cur = next)
1025 GNUNET_ATS_solver_generate_preferences_stop(cur);
1036 print_op (enum OperationType op)
1039 case SOLVER_OP_ADD_ADDRESS:
1040 return "ADD_ADDRESS";
1041 case SOLVER_OP_DEL_ADDRESS:
1042 return "DEL_ADDRESS";
1043 case SOLVER_OP_START_SET_PREFERENCE:
1044 return "START_SET_PREFERENCE";
1045 case SOLVER_OP_STOP_SET_PREFERENCE:
1046 return "STOP_STOP_PREFERENCE";
1047 case SOLVER_OP_START_SET_PROPERTY:
1048 return "START_SET_PROPERTY";
1049 case SOLVER_OP_STOP_SET_PROPERTY:
1050 return "STOP_SET_PROPERTY";
1051 case SOLVER_OP_START_REQUEST:
1052 return "START_REQUEST";
1053 case SOLVER_OP_STOP_REQUEST:
1054 return "STOP_REQUEST";
1061 static struct Experiment *
1062 create_experiment ()
1064 struct Experiment *e;
1065 e = GNUNET_new (struct Experiment);
1068 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1073 free_experiment (struct Experiment *e)
1075 struct Episode *cur;
1076 struct Episode *next;
1077 struct GNUNET_ATS_TEST_Operation *cur_o;
1078 struct GNUNET_ATS_TEST_Operation *next_o;
1081 for (cur = next; NULL != cur; cur = next)
1086 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1088 next_o = cur_o->next;
1089 GNUNET_free_non_null (cur_o->address);
1090 GNUNET_free_non_null (cur_o->plugin);
1091 GNUNET_free (cur_o);
1096 GNUNET_free_non_null (e->name);
1097 GNUNET_free_non_null (e->log_prefix);
1098 GNUNET_free_non_null (e->cfg_file);
1104 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1108 const struct GNUNET_CONFIGURATION_Handle *cfg)
1114 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1115 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1116 sec_name, op_name, &o->peer_id))
1118 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1119 op_counter, "ADD_ADDRESS", op_name);
1120 GNUNET_free (op_name);
1121 return GNUNET_SYSERR;
1123 GNUNET_free (op_name);
1126 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1127 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1128 sec_name, op_name, &o->address_id))
1130 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1131 op_counter, "ADD_ADDRESS", op_name);
1132 GNUNET_free (op_name);
1133 return GNUNET_SYSERR;
1135 GNUNET_free (op_name);
1138 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1139 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1140 sec_name, op_name, &o->plugin))
1142 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1143 op_counter, "ADD_ADDRESS", op_name);
1144 GNUNET_free (op_name);
1145 return GNUNET_SYSERR;
1147 GNUNET_free (op_name);
1150 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1151 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1152 sec_name, op_name, &o->address))
1154 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1155 op_counter, "ADD_ADDRESS", op_name);
1156 GNUNET_free (op_name);
1157 return GNUNET_SYSERR;
1159 GNUNET_free (op_name);
1162 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1163 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1164 sec_name, op_name, &o->address_session))
1166 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1167 op_counter, "ADD_ADDRESS", op_name);
1168 GNUNET_free (op_name);
1169 return GNUNET_SYSERR;
1171 GNUNET_free (op_name);
1174 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
1175 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1176 sec_name, op_name, &op_network))
1178 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
1179 op_counter, "ADD_ADDRESS", op_name);
1180 GNUNET_free (op_name);
1181 return GNUNET_SYSERR;
1185 GNUNET_STRINGS_utf8_toupper (op_network,op_network);
1186 if (0 == strcmp(op_network, "UNSPECIFIED"))
1188 o->address_network = GNUNET_ATS_NET_UNSPECIFIED;
1190 else if (0 == strcmp(op_network, "LOOPBACK"))
1192 o->address_network = GNUNET_ATS_NET_LOOPBACK;
1194 else if (0 == strcmp(op_network, "LAN"))
1196 o->address_network = GNUNET_ATS_NET_LAN;
1198 else if (0 == strcmp(op_network, "WAN"))
1200 o->address_network = GNUNET_ATS_NET_WAN;
1202 else if (0 == strcmp(op_network, "WLAN"))
1204 o->address_network = GNUNET_ATS_NET_WLAN;
1206 else if (0 == strcmp(op_network, "BT"))
1208 o->address_network = GNUNET_ATS_NET_BT;
1212 fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1213 op_counter, "ADD_ADDRESS", op_name, op_network);
1214 GNUNET_free (op_network);
1215 GNUNET_free (op_name);
1216 return GNUNET_SYSERR;
1219 GNUNET_free (op_network);
1220 GNUNET_free (op_name);
1222 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1223 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1224 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1230 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1234 const struct GNUNET_CONFIGURATION_Handle *cfg)
1240 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1241 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1242 sec_name, op_name, &o->peer_id))
1244 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1245 op_counter, "DEL_ADDRESS", op_name);
1246 GNUNET_free (op_name);
1247 return GNUNET_SYSERR;
1249 GNUNET_free (op_name);
1252 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1253 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1254 sec_name, op_name, &o->address_id))
1256 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1257 op_counter, "DEL_ADDRESS", op_name);
1258 GNUNET_free (op_name);
1259 return GNUNET_SYSERR;
1261 GNUNET_free (op_name);
1264 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
1265 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1266 sec_name, op_name, &o->plugin))
1268 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1269 op_counter, "DEL_ADDRESS", op_name);
1270 GNUNET_free (op_name);
1271 return GNUNET_SYSERR;
1273 GNUNET_free (op_name);
1276 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
1277 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1278 sec_name, op_name, &o->address))
1280 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1281 op_counter, "DEL_ADDRESS", op_name);
1282 GNUNET_free (op_name);
1283 return GNUNET_SYSERR;
1285 GNUNET_free (op_name);
1288 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
1289 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1290 sec_name, op_name, &o->address_session))
1292 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
1293 op_counter, "DEL_ADDRESS", op_name);
1294 GNUNET_free (op_name);
1295 return GNUNET_SYSERR;
1297 GNUNET_free (op_name);
1300 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
1301 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1302 sec_name, op_name, &op_network))
1304 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
1305 op_counter, "ADD_ADDRESS", op_name);
1306 GNUNET_free (op_name);
1307 return GNUNET_SYSERR;
1311 GNUNET_STRINGS_utf8_toupper (op_network,op_network);
1312 if (0 == strcmp(op_network, "UNSPECIFIED"))
1314 o->address_network = GNUNET_ATS_NET_UNSPECIFIED;
1316 else if (0 == strcmp(op_network, "LOOPBACK"))
1318 o->address_network = GNUNET_ATS_NET_LOOPBACK;
1320 else if (0 == strcmp(op_network, "LAN"))
1322 o->address_network = GNUNET_ATS_NET_LAN;
1324 else if (0 == strcmp(op_network, "WAN"))
1326 o->address_network = GNUNET_ATS_NET_WAN;
1328 else if (0 == strcmp(op_network, "WLAN"))
1330 o->address_network = GNUNET_ATS_NET_WLAN;
1332 else if (0 == strcmp(op_network, "BT"))
1334 o->address_network = GNUNET_ATS_NET_BT;
1338 fprintf (stderr, "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1339 op_counter, "ADD_ADDRESS", op_name, op_network);
1340 GNUNET_free (op_network);
1341 GNUNET_free (op_name);
1342 return GNUNET_SYSERR;
1345 GNUNET_free (op_network);
1346 GNUNET_free (op_name);
1348 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1349 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1350 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1355 static enum GNUNET_ATS_Property
1356 parse_preference_string (const char * str)
1359 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1361 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1362 if (0 == strcmp(str, props[c]))
1368 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1372 const struct GNUNET_CONFIGURATION_Handle *cfg)
1379 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1380 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1381 sec_name, op_name, &o->peer_id))
1383 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1384 op_counter, "START_SET_PREFERENCE", op_name);
1385 GNUNET_free (op_name);
1386 return GNUNET_SYSERR;
1388 GNUNET_free (op_name);
1391 GNUNET_asprintf(&op_name, "op-%u-client-id", op_counter);
1392 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1393 sec_name, op_name, &o->client_id))
1395 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1396 op_counter, "START_SET_PREFERENCE", op_name);
1397 GNUNET_free (op_name);
1398 return GNUNET_SYSERR;
1400 GNUNET_free (op_name);
1403 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1404 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1405 sec_name, op_name, &type)) )
1407 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1408 op_counter, "START_SET_PREFERENCE", op_name);
1409 GNUNET_free (op_name);
1410 return GNUNET_SYSERR;
1413 /* Load arguments for set_rate, start_send, set_preference */
1414 if (0 == strcmp (type, "constant"))
1416 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1418 else if (0 == strcmp (type, "linear"))
1420 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1422 else if (0 == strcmp (type, "sinus"))
1424 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1426 else if (0 == strcmp (type, "random"))
1428 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1432 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1433 op_counter, op_name, e->id);
1435 GNUNET_free (op_name);
1436 return GNUNET_SYSERR;
1439 GNUNET_free (op_name);
1443 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1444 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1445 sec_name, op_name, &o->base_rate))
1447 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1448 op_counter, op_name, e->id);
1449 GNUNET_free (op_name);
1450 return GNUNET_SYSERR;
1452 GNUNET_free (op_name);
1456 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1457 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1458 sec_name, op_name, &o->max_rate))
1460 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1461 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1462 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1464 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1465 op_counter, op_name, e->id);
1466 GNUNET_free (op_name);
1467 return GNUNET_SYSERR;
1470 GNUNET_free (op_name);
1473 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1474 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1475 sec_name, op_name, &o->period))
1477 o->period = e->duration;
1479 GNUNET_free (op_name);
1482 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1483 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1484 sec_name, op_name, &o->frequency))
1486 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1487 op_counter, op_name, e->id);
1488 GNUNET_free (op_name);
1489 return GNUNET_SYSERR;
1491 GNUNET_free (op_name);
1493 /* Get preference */
1494 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1495 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1496 sec_name, op_name, &pref))
1498 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1499 op_counter, op_name, e->id);
1500 GNUNET_free (op_name);
1501 return GNUNET_SYSERR;
1504 if (0 == (o->pref_type = parse_preference_string(pref)))
1506 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1507 op_counter, op_name, e->id);
1508 GNUNET_free (op_name);
1510 return GNUNET_SYSERR;
1513 GNUNET_free (op_name);
1515 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1516 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1517 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1518 GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
1524 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1528 const struct GNUNET_CONFIGURATION_Handle *cfg)
1534 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1535 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1536 sec_name, op_name, &o->peer_id))
1538 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1539 op_counter, "STOP_SET_PREFERENCE", op_name);
1540 GNUNET_free (op_name);
1541 return GNUNET_SYSERR;
1543 GNUNET_free (op_name);
1546 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1547 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1548 sec_name, op_name, &o->address_id))
1550 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1551 op_counter, "STOP_SET_PREFERENCE", op_name);
1552 GNUNET_free (op_name);
1553 return GNUNET_SYSERR;
1555 GNUNET_free (op_name);
1557 /* Get preference */
1558 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1559 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1560 sec_name, op_name, &pref))
1562 fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
1563 op_counter, "STOP_SET_PREFERENCE", op_name);
1564 GNUNET_free (op_name);
1565 return GNUNET_SYSERR;
1568 if (0 == (o->pref_type = parse_preference_string(pref)))
1570 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1571 op_counter, op_name, e->id);
1572 GNUNET_free (op_name);
1574 return GNUNET_SYSERR;
1577 GNUNET_free (op_name);
1579 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1580 "Found operation %s: [%llu:%llu]: %s\n",
1581 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1582 GNUNET_ATS_print_preference_type(o->pref_type));
1586 static enum GNUNET_ATS_Property
1587 parse_property_string (const char * str)
1590 char *props[GNUNET_ATS_PropertyCount] = GNUNET_ATS_PropertyStrings;
1592 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1593 if (0 == strcmp(str, props[c]))
1599 load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
1603 const struct GNUNET_CONFIGURATION_Handle *cfg)
1610 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1611 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1612 sec_name, op_name, &o->peer_id))
1614 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1615 op_counter, "START_SET_PROPERTY", op_name);
1616 GNUNET_free (op_name);
1617 return GNUNET_SYSERR;
1619 GNUNET_free (op_name);
1622 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1623 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1624 sec_name, op_name, &o->address_id))
1626 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1627 op_counter, "START_SET_PROPERTY", op_name);
1628 GNUNET_free (op_name);
1629 return GNUNET_SYSERR;
1631 GNUNET_free (op_name);
1634 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
1635 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1636 sec_name, op_name, &type)) )
1638 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1639 op_counter, "START_SET_PROPERTY", op_name);
1640 GNUNET_free (op_name);
1641 return GNUNET_SYSERR;
1644 /* Load arguments for set_rate, start_send, set_preference */
1645 if (0 == strcmp (type, "constant"))
1647 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1649 else if (0 == strcmp (type, "linear"))
1651 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1653 else if (0 == strcmp (type, "sinus"))
1655 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1657 else if (0 == strcmp (type, "random"))
1659 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1663 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1664 op_counter, op_name, e->id);
1666 GNUNET_free (op_name);
1667 return GNUNET_SYSERR;
1670 GNUNET_free (op_name);
1674 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1675 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1676 sec_name, op_name, &o->base_rate))
1678 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1679 op_counter, op_name, e->id);
1680 GNUNET_free (op_name);
1681 return GNUNET_SYSERR;
1683 GNUNET_free (op_name);
1687 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1688 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1689 sec_name, op_name, &o->max_rate))
1691 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1692 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1693 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1695 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1696 op_counter, op_name, e->id);
1697 GNUNET_free (op_name);
1698 return GNUNET_SYSERR;
1701 GNUNET_free (op_name);
1704 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1705 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1706 sec_name, op_name, &o->period))
1708 o->period = e->duration;
1710 GNUNET_free (op_name);
1713 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1714 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1715 sec_name, op_name, &o->frequency))
1717 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1718 op_counter, op_name, e->id);
1719 GNUNET_free (op_name);
1720 return GNUNET_SYSERR;
1722 GNUNET_free (op_name);
1724 /* Get preference */
1725 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1726 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1727 sec_name, op_name, &prop))
1729 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1730 op_counter, op_name, e->id);
1731 GNUNET_free (op_name);
1732 GNUNET_free_non_null (prop);
1733 return GNUNET_SYSERR;
1736 if (0 == (o->prop_type = parse_property_string(prop)))
1738 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1739 op_counter, op_name, e->id);
1740 GNUNET_free (op_name);
1742 return GNUNET_SYSERR;
1746 GNUNET_free (op_name);
1748 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1749 "Found operation %s: [%llu:%llu] %s = %llu\n",
1750 "START_SET_PROPERTY", o->peer_id, o->address_id,
1751 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1757 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1761 const struct GNUNET_CONFIGURATION_Handle *cfg)
1767 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1768 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1769 sec_name, op_name, &o->peer_id))
1771 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1772 op_counter, "STOP_SET_PROPERTY", op_name);
1773 GNUNET_free (op_name);
1774 return GNUNET_SYSERR;
1776 GNUNET_free (op_name);
1779 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
1780 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1781 sec_name, op_name, &o->address_id))
1783 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
1784 op_counter, "STOP_SET_PROPERTY", op_name);
1785 GNUNET_free (op_name);
1786 return GNUNET_SYSERR;
1788 GNUNET_free (op_name);
1791 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
1792 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1793 sec_name, op_name, &pref))
1795 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
1796 op_counter, "STOP_SET_PROPERTY", op_name);
1797 GNUNET_free (op_name);
1798 GNUNET_free_non_null (pref);
1799 return GNUNET_SYSERR;
1802 if (0 == (o->prop_type = parse_property_string(pref)))
1804 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1805 op_counter, op_name, e->id);
1806 GNUNET_free (op_name);
1807 GNUNET_free_non_null (pref);
1808 return GNUNET_SYSERR;
1812 GNUNET_free (op_name);
1814 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1815 "Found operation %s: [%llu:%llu] %s\n",
1816 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
1817 GNUNET_ATS_print_property_type (o->prop_type));
1824 load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
1828 const struct GNUNET_CONFIGURATION_Handle *cfg)
1833 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1834 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1835 sec_name, op_name, &o->peer_id))
1837 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1838 op_counter, "START_REQUEST", op_name);
1839 GNUNET_free (op_name);
1840 return GNUNET_SYSERR;
1842 GNUNET_free (op_name);
1847 load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
1851 const struct GNUNET_CONFIGURATION_Handle *cfg)
1856 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
1857 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1858 sec_name, op_name, &o->peer_id))
1860 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1861 op_counter, "STOP_REQUEST", op_name);
1862 GNUNET_free (op_name);
1863 return GNUNET_SYSERR;
1865 GNUNET_free (op_name);
1871 load_episode (struct Experiment *e, struct Episode *cur,
1872 struct GNUNET_CONFIGURATION_Handle *cfg)
1874 struct GNUNET_ATS_TEST_Operation *o;
1880 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n",cur->id);
1881 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
1885 /* Load operation */
1886 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
1887 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1888 sec_name, op_name, &op))
1890 GNUNET_free (op_name);
1893 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
1894 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
1897 /* operations = set_rate, start_send, stop_send, set_preference */
1898 if (0 == strcmp (op, "address_add"))
1900 o->type = SOLVER_OP_ADD_ADDRESS;
1901 res = load_op_add_address (o, cur,
1902 op_counter, sec_name, cfg);
1904 else if (0 == strcmp (op, "address_del"))
1906 o->type = SOLVER_OP_DEL_ADDRESS;
1907 res = load_op_del_address (o, cur,
1908 op_counter, sec_name, cfg);
1910 else if (0 == strcmp (op, "start_set_property"))
1912 o->type = SOLVER_OP_START_SET_PROPERTY;
1913 res = load_op_start_set_property (o, cur,
1914 op_counter, sec_name, cfg);
1916 else if (0 == strcmp (op, "stop_set_property"))
1918 o->type = SOLVER_OP_STOP_SET_PROPERTY;
1919 res = load_op_stop_set_property (o, cur,
1920 op_counter, sec_name, cfg);
1922 else if (0 == strcmp (op, "start_set_preference"))
1924 o->type = SOLVER_OP_START_SET_PREFERENCE;
1925 res = load_op_start_set_preference (o, cur,
1926 op_counter, sec_name, cfg);
1928 else if (0 == strcmp (op, "stop_set_preference"))
1930 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
1931 res = load_op_stop_set_preference (o, cur,
1932 op_counter, sec_name, cfg);
1934 else if (0 == strcmp (op, "start_request"))
1936 o->type = SOLVER_OP_START_REQUEST;
1937 res = load_op_start_request (o, cur,
1938 op_counter, sec_name, cfg);
1940 else if (0 == strcmp (op, "stop_request"))
1942 o->type = SOLVER_OP_STOP_REQUEST;
1943 res = load_op_stop_request(o, cur,
1944 op_counter, sec_name, cfg);
1948 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
1949 op_counter, op, cur->id);
1950 res = GNUNET_SYSERR;
1954 GNUNET_free (op_name);
1956 if (GNUNET_SYSERR == res)
1959 GNUNET_free (sec_name);
1960 return GNUNET_SYSERR;
1963 GNUNET_CONTAINER_DLL_insert_tail (cur->head,cur->tail, o);
1966 GNUNET_free (sec_name);
1971 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
1975 struct GNUNET_TIME_Relative e_duration;
1976 struct Episode *cur;
1977 struct Episode *last;
1983 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
1984 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
1985 sec_name, "duration", &e_duration))
1987 GNUNET_free (sec_name);
1991 cur = GNUNET_new (struct Episode);
1992 cur->duration = e_duration;
1993 cur->id = e_counter;
1995 if (GNUNET_OK != load_episode (e, cur, cfg))
1997 GNUNET_free (sec_name);
1999 return GNUNET_SYSERR;
2002 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2004 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
2006 /* Update experiment */
2008 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
2009 /* Put in linked list */
2015 GNUNET_free (sec_name);
2023 timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
2025 struct Experiment *e = cls;
2026 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
2027 fprintf (stderr, "Experiment timeout!\n");
2029 if (GNUNET_SCHEDULER_NO_TASK != e->episode_timeout_task)
2031 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2032 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
2035 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
2039 struct ATS_Address *
2040 create_ats_address (const struct GNUNET_PeerIdentity *peer,
2041 const char *plugin_name,
2042 const void *plugin_addr, size_t plugin_addr_len,
2043 uint32_t session_id)
2045 struct ATS_Address *aa = NULL;
2047 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len + strlen (plugin_name) + 1);
2049 aa->addr_len = plugin_addr_len;
2051 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2052 memcpy (&aa[1], plugin_addr, plugin_addr_len);
2053 memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2054 aa->session_id = session_id;
2055 aa->active = GNUNET_NO;
2056 aa->used = GNUNET_NO;
2057 aa->solver_information = NULL;
2058 aa->assigned_bw_in = GNUNET_BANDWIDTH_value_init(0);
2059 aa->assigned_bw_out = GNUNET_BANDWIDTH_value_init(0);
2066 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2069 struct TestAddress *a;
2072 if (NULL == (p = find_peer_by_id (op->peer_id)))
2074 p = GNUNET_new (struct TestPeer);
2075 p->id = op->peer_id;
2076 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2077 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2079 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2080 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2083 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2086 if (NULL != (find_address_by_id (p, op->address_id)))
2088 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2089 op->address_id, op->peer_id);
2093 a = GNUNET_new (struct TestAddress);
2094 a->aid = op->address_id;
2095 a->network = op->address_network;
2096 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2097 strlen (op->address) + 1, op->address_session);
2098 memset (&p->peer_id, op->peer_id, sizeof (p->peer_id));
2099 GNUNET_CONTAINER_DLL_insert (p->addr_head, p->addr_tail, a);
2101 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2102 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2104 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2105 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2107 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding address %u for peer %u in network `%s'\n",
2108 op->address_id, op->peer_id, GNUNET_ATS_print_network_type(op->address_network));
2110 sh->env.sf.s_add (sh->solver, a->ats_addr, op->address_network);
2116 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2119 struct TestAddress *a;
2120 struct AddressLookupCtx ctx;
2121 struct PropertyGenerator *pg;
2123 if (NULL == (p = find_peer_by_id (op->peer_id)))
2126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2127 "Deleting address for unknown peer %u\n", op->peer_id);
2131 ctx.plugin = op->plugin;
2132 ctx.addr = op->address;
2134 GNUNET_CONTAINER_multipeermap_get_multiple (sh->addresses, &p->peer_id,
2135 find_address_it, &ctx);
2136 if (NULL == ctx.res)
2139 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2140 "Deleting unknown address for peer %u\n", op->peer_id);
2144 if (NULL == (a =find_address_by_id (p, op->address_id)))
2147 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2148 "Deleting address for unknown peer %u\n", op->peer_id);
2152 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2154 GNUNET_ATS_solver_generate_property_stop (pg);
2157 GNUNET_CONTAINER_DLL_remove(p->addr_head, p->addr_tail, a);
2160 GNUNET_CONTAINER_multipeermap_remove (sh->addresses, &p->peer_id, ctx.res);
2162 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Removing address %u for peer %u\n",
2163 op->address_id, op->peer_id);
2165 sh->env.sf.s_del (sh->solver, ctx.res, GNUNET_NO);
2166 GNUNET_free (ctx.res);
2171 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2173 struct PropertyGenerator *pg;
2175 struct TestAddress *a;
2177 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2179 GNUNET_ATS_solver_generate_property_stop (pg);
2183 if (NULL == (p = find_peer_by_id (op->peer_id)))
2186 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2187 "Starting property generation for unknown peer %u\n", op->peer_id);
2191 if (NULL == (a = find_address_by_id (p, op->address_id)))
2194 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2195 "Setting property for unknown address %u\n", op->peer_id);
2199 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2211 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2213 struct PropertyGenerator *pg = find_prop_gen(op->peer_id, op->address_id,
2216 GNUNET_ATS_solver_generate_property_stop (pg);
2220 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2222 struct PreferenceGenerator *pg;
2223 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2225 GNUNET_ATS_solver_generate_preferences_stop (pg);
2229 if (NULL == (find_peer_by_id (op->peer_id)))
2232 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2233 "Starting preference generation for unknown peer %u\n", op->peer_id);
2237 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2249 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2251 struct PreferenceGenerator *pg = find_pref_gen(op->peer_id,
2254 GNUNET_ATS_solver_generate_preferences_stop (pg);
2259 enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2262 const struct ATS_Address *res;
2264 if (NULL == (p = find_peer_by_id (op->peer_id)))
2267 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2268 "Requesting address for unknown peer %u\n", op->peer_id);
2272 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2275 res = sh->env.sf.s_get (sh->solver, &p->peer_id);
2283 enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
2287 if (NULL == (p = find_peer_by_id (op->peer_id)))
2290 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2291 "Requesting address for unknown peer %u\n", op->peer_id);
2295 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop requesting address for peer %u\n",
2298 sh->env.sf.s_get_stop (sh->solver, &p->peer_id);
2301 static void enforce_episode (struct Episode *ep)
2303 struct GNUNET_ATS_TEST_Operation *cur;
2304 for (cur = ep->head; NULL != cur; cur = cur->next)
2306 switch (cur->type) {
2307 case SOLVER_OP_ADD_ADDRESS:
2308 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2309 print_op (cur->type), cur->peer_id, cur->address_id);
2310 enforce_add_address (cur);
2312 case SOLVER_OP_DEL_ADDRESS:
2313 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2314 print_op (cur->type), cur->peer_id, cur->address_id);
2315 enforce_del_address (cur);
2317 case SOLVER_OP_START_SET_PROPERTY:
2318 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2319 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2320 enforce_start_property (cur);
2322 case SOLVER_OP_STOP_SET_PROPERTY:
2323 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2324 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2325 enforce_stop_property (cur);
2327 case SOLVER_OP_START_SET_PREFERENCE:
2328 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2329 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2330 enforce_start_preference (cur);
2332 case SOLVER_OP_STOP_SET_PREFERENCE:
2333 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2334 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
2335 enforce_stop_preference (cur);
2337 case SOLVER_OP_START_REQUEST:
2338 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2339 print_op (cur->type), cur->peer_id);
2340 enforce_start_request (cur);
2342 case SOLVER_OP_STOP_REQUEST:
2343 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2344 print_op (cur->type), cur->peer_id);
2345 enforce_stop_request (cur);
2354 timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
2356 struct Experiment *e = cls;
2357 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
2358 if (NULL != e->ep_done_cb)
2359 e->ep_done_cb (e->cur);
2361 /* Scheduling next */
2362 e->cur = e->cur->next;
2366 fprintf (stderr, "Last episode done!\n");
2367 if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task)
2369 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2370 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
2372 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
2376 fprintf (stderr, "Running episode %u with timeout %s\n",
2378 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2379 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2380 &timeout_episode, e);
2381 enforce_episode(e->cur);
2388 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2389 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
2390 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
2392 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2393 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
2394 e->e_done_cb = e_done_cb;
2395 e->ep_done_cb = ep_done_cb;
2396 e->start_time = GNUNET_TIME_absolute_get();
2398 /* Start total time out */
2399 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2400 &timeout_experiment, e);
2403 if (NULL == e->start)
2410 fprintf (stderr, "Running episode %u with timeout %s\n",
2412 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
2413 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2414 &timeout_episode, e);
2415 enforce_episode(e->cur);
2420 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2422 if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task)
2424 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2425 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
2427 if (GNUNET_SCHEDULER_NO_TASK != e->episode_timeout_task)
2429 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2430 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
2434 GNUNET_CONFIGURATION_destroy(e->cfg);
2437 free_experiment (e);
2442 GNUNET_ATS_solvers_experimentation_load (char *filename)
2444 struct Experiment *e;
2445 struct GNUNET_CONFIGURATION_Handle *cfg;
2448 cfg = GNUNET_CONFIGURATION_create();
2449 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2451 fprintf (stderr, "Failed to load `%s'\n", filename);
2452 GNUNET_CONFIGURATION_destroy (cfg);
2456 e = create_experiment ();
2458 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2461 fprintf (stderr, "Invalid %s", "name");
2462 free_experiment (e);
2466 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2468 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2469 "log_prefix", &e->log_prefix))
2471 fprintf (stderr, "Invalid %s", "name");
2472 free_experiment (e);
2476 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2479 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2480 "cfg_file", &e->cfg_file))
2482 fprintf (stderr, "Invalid %s", "cfg_file");
2483 free_experiment (e);
2488 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n", e->cfg_file);
2489 e->cfg = GNUNET_CONFIGURATION_create();
2490 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2492 fprintf (stderr, "Invalid configuration %s", "cfg_file");
2493 free_experiment (e);
2499 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2500 "log_freq", &e->log_freq))
2502 fprintf (stderr, "Invalid %s", "log_freq");
2503 free_experiment (e);
2507 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2508 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
2510 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2511 "max_duration", &e->max_duration))
2513 fprintf (stderr, "Invalid %s", "max_duration");
2514 free_experiment (e);
2518 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2519 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
2521 if (GNUNET_SYSERR == load_episodes (e, cfg))
2523 GNUNET_ATS_solvers_experimentation_stop (e);
2524 GNUNET_CONFIGURATION_destroy (cfg);
2526 fprintf (stderr, "Failed to load experiment\n");
2529 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded %u episodes with total duration %s\n",
2531 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
2533 GNUNET_CONFIGURATION_destroy (cfg);
2544 free_all_it (void *cls,
2545 const struct GNUNET_PeerIdentity *key,
2548 struct ATS_Address *address = value;
2549 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (sh->env.addresses,
2551 GNUNET_free (address);
2557 GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2559 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2561 GNUNET_PLUGIN_unload (sh->plugin, sh->solver);
2563 GAS_normalization_stop();
2565 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses, &free_all_it, NULL);
2566 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
2567 GNUNET_free (sh->plugin);
2572 * Load quotas for networks from configuration
2574 * @param cfg configuration handle
2575 * @param out_dest where to write outbound quotas
2576 * @param in_dest where to write inbound quotas
2577 * @param dest_length length of inbound and outbound arrays
2578 * @return number of networks loaded
2581 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2582 unsigned long long *out_dest,
2583 unsigned long long *in_dest,
2586 char *network_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
2587 char * entry_in = NULL;
2588 char * entry_out = NULL;
2589 char * quota_out_str;
2590 char * quota_in_str;
2594 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
2598 GNUNET_asprintf (&entry_out, "%s_QUOTA_OUT", network_str[c]);
2599 GNUNET_asprintf (&entry_in, "%s_QUOTA_IN", network_str[c]);
2602 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
2605 if (0 == strcmp(quota_out_str, BIG_M_STRING))
2607 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2610 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
2612 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
2615 if (GNUNET_NO == res)
2617 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2618 network_str[c], quota_out_str, GNUNET_ATS_DefaultBandwidth);
2619 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2623 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Outbound quota configure for network `%s' is %llu\n"),
2624 network_str[c], out_dest[c]);
2626 GNUNET_free (quota_out_str);
2630 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
2631 network_str[c], GNUNET_ATS_DefaultBandwidth);
2632 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2636 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
2639 if (0 == strcmp(quota_in_str, BIG_M_STRING))
2641 in_dest[c] = GNUNET_ATS_MaxBandwidth;
2644 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
2646 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
2649 if (GNUNET_NO == res)
2651 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2652 network_str[c], quota_in_str, GNUNET_ATS_DefaultBandwidth);
2653 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
2657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Inbound quota configured for network `%s' is %llu\n"),
2658 network_str[c], in_dest[c]);
2660 GNUNET_free (quota_in_str);
2664 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
2665 network_str[c], GNUNET_ATS_DefaultBandwidth);
2666 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2668 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loaded quota for network `%s' (in/out): %llu %llu\n", network_str[c], in_dest[c], out_dest[c]);
2669 GNUNET_free (entry_out);
2670 GNUNET_free (entry_in);
2672 return GNUNET_ATS_NetworkTypeCount;
2676 * Information callback for the solver
2678 * @param cls the closure
2679 * @param op the solver operation
2680 * @param stat status of the solver operation
2681 * @param add additional solver information
2684 solver_info_cb (void *cls,
2685 enum GAS_Solver_Operation op,
2686 enum GAS_Solver_Status stat,
2687 enum GAS_Solver_Additional_Information add)
2692 add_info = "GAS_INFO_NONE";
2695 add_info = "GAS_INFO_MLP_FULL";
2697 case GAS_INFO_UPDATED:
2698 add_info = "GAS_INFO_MLP_UPDATED";
2700 case GAS_INFO_PROP_ALL:
2701 add_info = "GAS_INFO_PROP_ALL";
2703 case GAS_INFO_PROP_SINGLE:
2704 add_info = "GAS_INFO_PROP_SINGLE";
2707 add_info = "INVALID";
2713 case GAS_OP_SOLVE_START:
2714 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2715 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
2716 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2718 case GAS_OP_SOLVE_STOP:
2719 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2720 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
2721 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
2724 case GAS_OP_SOLVE_SETUP_START:
2725 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2726 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
2727 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2730 case GAS_OP_SOLVE_SETUP_STOP:
2731 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2732 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
2733 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2736 case GAS_OP_SOLVE_MLP_LP_START:
2737 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2738 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
2739 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2741 case GAS_OP_SOLVE_MLP_LP_STOP:
2742 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2743 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
2744 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2747 case GAS_OP_SOLVE_MLP_MLP_START:
2748 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2749 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
2750 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2752 case GAS_OP_SOLVE_MLP_MLP_STOP:
2753 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2754 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
2755 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2757 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
2758 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2759 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
2760 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2762 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
2763 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2764 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
2765 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
2773 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
2775 if ( (0 == ntohl (address->assigned_bw_out.value__)) &&
2776 (0 == ntohl (address->assigned_bw_in.value__)) )
2778 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2779 "Solver notified to disconnect peer `%s'\n",
2780 GNUNET_i2s (&address->peer));
2784 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2785 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
2786 GNUNET_i2s (&address->peer),
2788 (unsigned int) ntohl (address->assigned_bw_out.value__),
2789 (unsigned int) ntohl (address->assigned_bw_in.value__));
2790 /*if (GNUNET_YES == ph.bulk_running)
2796 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
2799 if (GNUNET_YES == opt_disable_normalization)
2801 if (NULL == (p = find_peer_by_pid (id)))
2806 return GAS_normalization_get_preferences_by_peer (id);
2811 get_property_cb (void *cls, const struct ATS_Address *address)
2814 struct TestAddress *a;
2816 if (GNUNET_YES == opt_disable_normalization)
2818 p = find_peer_by_pid (&address->peer);
2819 a = find_address_by_ats_address (p, address);
2823 return GAS_normalization_get_properties ((struct ATS_Address *) address);
2827 set_updated_property ( struct ATS_Address *address, uint32_t type, double prop_rel)
2830 struct TestAddress *a;
2832 if (NULL == (p = find_peer_by_pid (&address->peer)))
2838 if (NULL == (a = find_address_by_ats_address (p, address)))
2843 a->prop_norm[type] = prop_rel;
2844 sh->env.sf.s_address_update_property (sh->solver, address, type, a->prop_abs [type], prop_rel);
2849 normalized_property_changed_cb (void *cls, struct ATS_Address *address,
2850 uint32_t type, double prop_rel)
2852 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2853 "Normalized property %s for peer `%s' changed to %.3f \n",
2854 GNUNET_ATS_print_property_type (type), GNUNET_i2s (&address->peer),
2857 set_updated_property (address, type, prop_rel);
2861 set_updated_preference (const struct GNUNET_PeerIdentity *peer,
2862 enum GNUNET_ATS_PreferenceKind kind,
2867 if (NULL == (p = find_peer_by_pid (peer)))
2873 p->pref_norm[kind] = pref_rel;
2874 sh->env.sf.s_pref (sh->solver, peer, kind, pref_rel);
2879 normalized_preference_changed_cb (void *cls,
2880 const struct GNUNET_PeerIdentity *peer,
2881 enum GNUNET_ATS_PreferenceKind kind,
2884 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2885 "Normalized preference %s for peer `%s' changed to %.3f \n",
2886 GNUNET_ATS_print_preference_type (kind), GNUNET_i2s (peer),
2889 set_updated_preference(peer, kind, pref_rel);
2893 struct SolverHandle *
2894 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
2896 struct SolverHandle *sh;
2901 case GNUNET_ATS_SOLVER_PROPORTIONAL:
2902 solver_str = "proportional";
2904 case GNUNET_ATS_SOLVER_MLP:
2907 case GNUNET_ATS_SOLVER_RIL:
2916 sh = GNUNET_new (struct SolverHandle);
2917 GNUNET_asprintf (&sh->plugin, "libgnunet_plugin_ats_%s", solver_str);
2919 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
2920 /* setup environment */
2921 sh->env.cfg = e->cfg;
2922 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
2923 sh->env.addresses = sh->addresses;
2924 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
2925 sh->env.get_preferences = &get_preferences_cb;
2926 sh->env.get_property = &get_property_cb;
2927 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
2928 sh->env.info_cb = &solver_info_cb;
2929 sh->env.info_cb_cls = NULL;
2930 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
2931 int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
2932 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
2933 sh->env.networks[c] = networks[c];
2936 /* start normalization */
2937 GAS_normalization_start (&normalized_preference_changed_cb, NULL,
2938 &normalized_property_changed_cb, NULL );
2941 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
2942 sh->env.out_quota, sh->env.in_quota, GNUNET_ATS_NetworkTypeCount))
2945 GNUNET_free (sh->plugin);
2951 sh->solver = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
2952 if (NULL == sh->solver)
2954 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
2956 GNUNET_free (sh->plugin);
2967 struct TestPeer *cur;
2968 struct TestPeer *next;
2970 struct TestAddress *cur_a;
2971 struct TestAddress *next_a;
2974 GNUNET_ATS_solver_logging_stop (l);
2976 /* Stop all preference generation */
2977 GNUNET_ATS_solver_generate_preferences_stop_all ();
2979 /* Stop all property generation */
2980 GNUNET_ATS_solver_generate_property_stop_all ();
2984 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
2985 GNUNET_ATS_solver_logging_eval (l);
2989 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
2990 GNUNET_ATS_solver_logging_write_to_disk (l);
2995 GNUNET_ATS_solver_logging_free (l);
2999 /* Clean up experiment */
3002 GNUNET_ATS_solvers_experimentation_stop (e);
3007 while (NULL != (cur = next))
3010 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3011 next_a = cur->addr_head;
3012 while (NULL != (cur_a = next_a))
3014 next_a = cur_a->next;
3015 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3016 GNUNET_free (cur_a);
3022 GNUNET_ATS_solvers_solver_stop (sh);
3031 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
3033 if (GNUNET_OK == success)
3034 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3035 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3037 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3039 GNUNET_SCHEDULER_add_now (&done, NULL);
3043 episode_done_cb (struct Episode *ep)
3045 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3058 GNUNET_ATS_solvers_experimentation_stop (e);
3063 GNUNET_ATS_solvers_solver_stop (sh);
3069 run (void *cls, char * const *args, const char *cfgfile,
3070 const struct GNUNET_CONFIGURATION_Handle *cfg)
3072 enum GNUNET_ATS_Solvers solver;
3075 if (NULL == opt_exp_file)
3077 fprintf (stderr, "No experiment given ...\n");
3083 if (NULL == opt_solver)
3085 fprintf (stderr, "No solver given ...\n");
3091 if (0 == strcmp(opt_solver, "mlp"))
3093 solver = GNUNET_ATS_SOLVER_MLP;
3095 else if (0 == strcmp(opt_solver, "proportional"))
3097 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3099 else if (0 == strcmp(opt_solver, "ril"))
3101 solver = GNUNET_ATS_SOLVER_RIL;
3105 fprintf (stderr, "No solver given ...");
3111 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3112 default_properties[c] = DEFAULT_REL_QUALITY;
3114 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3115 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3117 /* load experiment */
3118 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3119 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3122 fprintf (stderr, "Failed to load experiment ...\n");
3129 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3130 sh = GNUNET_ATS_solvers_solver_start (solver);
3133 fprintf (stderr, "Failed to start solver ...\n");
3140 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3141 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3143 /* run experiment */
3144 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3145 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3146 experiment_done_cb);
3153 * Main function of the benchmark
3155 * @param argc argument count
3156 * @param argv argument values
3159 main (int argc, char *argv[])
3161 opt_exp_file = NULL;
3163 opt_log = GNUNET_NO;
3164 opt_save = GNUNET_NO;
3168 static struct GNUNET_GETOPT_CommandLineOption options[] =
3170 { 's', "solver", NULL,
3171 gettext_noop ("solver to use"),
3172 1, &GNUNET_GETOPT_set_string, &opt_solver},
3173 { 'e', "experiment", NULL,
3174 gettext_noop ("experiment to use"),
3175 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
3176 { 'V', "verbose", NULL,
3177 gettext_noop ("be verbose"),
3178 0, &GNUNET_GETOPT_set_one, &opt_verbose},
3179 { 'p', "print", NULL,
3180 gettext_noop ("print logging"),
3181 0, &GNUNET_GETOPT_set_one, &opt_print},
3182 { 'f', "file", NULL,
3183 gettext_noop ("save logging to disk"),
3184 0, &GNUNET_GETOPT_set_one, &opt_save},
3186 gettext_noop ("disable normalization"),
3187 0, &GNUNET_GETOPT_set_one, &opt_disable_normalization},
3188 GNUNET_GETOPT_OPTION_END
3191 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3192 NULL, options, &run, argv[0]);
3196 /* end of file ats-testing-experiment.c*/