aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-ats-solver-eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/gnunet-ats-solver-eval.c')
-rw-r--r--src/ats/gnunet-ats-solver-eval.c3588
1 files changed, 0 insertions, 3588 deletions
diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c
deleted file mode 100644
index ba7994686..000000000
--- a/src/ats/gnunet-ats-solver-eval.c
+++ /dev/null
@@ -1,3588 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
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"
31
32#define BIG_M_STRING "unlimited"
33
34/**
35 * Handle for statistics.
36 */
37struct GNUNET_STATISTICS_Handle *GSA_stats;
38
39
40static struct Experiment *e;
41
42static struct LoggingHandle *l;
43
44static struct SolverHandle *sh;
45
46static struct TestPeer *peer_head;
47
48static struct TestPeer *peer_tail;
49
50static double default_properties[GNUNET_ATS_PropertyCount];
51static double default_preferences[GNUNET_ATS_PreferenceCount];
52
53/**
54 * cmd option -e: experiment file
55 */
56static char *opt_exp_file;
57
58static char *opt_solver;
59
60/**
61 * cmd option -l: enable logging
62 */
63static int opt_log;
64
65/**
66 * cmd option -p: enable plots
67 */
68static int opt_save;
69
70/**
71 * cmd option -v: verbose logs
72 */
73static int opt_verbose;
74
75/**
76 * cmd option -p: print logs
77 */
78static int opt_print;
79
80/**
81 * cmd option -d: disable normalization
82 */
83static int opt_disable_normalization;
84
85static int res;
86
87static void
88end_now ();
89
90
91static char *
92print_generator_type (enum GeneratorType g)
93{
94 switch (g)
95 {
96 case GNUNET_ATS_TEST_TG_CONSTANT:
97 return "CONSTANT";
98
99 case GNUNET_ATS_TEST_TG_LINEAR:
100 return "LINEAR";
101
102 case GNUNET_ATS_TEST_TG_RANDOM:
103 return "RANDOM";
104
105 case GNUNET_ATS_TEST_TG_SINUS:
106 return "SINUS";
107
108 default:
109 return "INVALID";
110 break;
111 }
112}
113
114
115static struct TestPeer *
116find_peer_by_id (int id)
117{
118 struct TestPeer *cur;
119
120 for (cur = peer_head; NULL != cur; cur = cur->next)
121 if (cur->id == id)
122 return cur;
123 return NULL;
124}
125
126
127static struct TestPeer *
128find_peer_by_pid (const struct GNUNET_PeerIdentity *pid)
129{
130 struct TestPeer *cur;
131
132 for (cur = peer_head; NULL != cur; cur = cur->next)
133 if (0 == GNUNET_memcmp (&cur->peer_id, pid))
134 return cur;
135 return NULL;
136}
137
138
139static struct TestAddress *
140find_address_by_id (struct TestPeer *peer, int aid)
141{
142 struct TestAddress *cur;
143
144 for (cur = peer->addr_head; NULL != cur; cur = cur->next)
145 if (cur->aid == aid)
146 return cur;
147 return NULL;
148}
149
150
151/**
152 * Logging
153 */
154void
155GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
156{
157 struct LoggingTimeStep *lts;
158 struct TestPeer *cur;
159 struct TestAddress *cur_addr;
160 struct LoggingPeer *log_p;
161 struct LoggingAddress *log_a;
162 int c;
163
164 lts = GNUNET_new (struct LoggingTimeStep);
165 GNUNET_CONTAINER_DLL_insert_tail (l->head, l->tail, lts);
166 lts->timestamp = GNUNET_TIME_absolute_get ();
167 if (NULL == lts->prev)
168 lts->delta = GNUNET_TIME_UNIT_ZERO;
169 else
170 lts->delta = GNUNET_TIME_absolute_get_duration (lts->prev->timestamp);
171
172 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging %llu, delta %llu\n",
173 lts->timestamp.abs_value_us, lts->delta.rel_value_us);
174
175
176 /* Store logging data here */
177 for (cur = peer_head; NULL != cur; cur = cur->next)
178 {
179 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
180 "Logging peer id %llu\n", cur->id);
181
182 log_p = GNUNET_new (struct LoggingPeer);
183 log_p->id = cur->id;
184 log_p->peer_id = cur->peer_id;
185 log_p->is_requested = cur->is_requested;
186 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
187 {
188 log_p->pref_abs[c] = cur->pref_abs[c];
189 log_p->pref_norm[c] = cur->pref_norm[c];
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
191 "\t %s = %.2f %.2f [abs/rel]\n",
192 GNUNET_ATS_print_preference_type (c),
193 log_p->pref_abs[c], log_p->pref_norm[c]);
194 }
195 GNUNET_CONTAINER_DLL_insert_tail (lts->head, lts->tail, log_p);
196
197 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
198 {
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
200 "Logging peer id %llu address %llu\n",
201 cur->id, cur_addr->aid);
202 log_a = GNUNET_new (struct LoggingAddress);
203 log_a->aid = cur_addr->aid;
204 log_a->active = cur_addr->ats_addr->active;
205 log_a->network = cur_addr->network;
206 log_a->assigned_bw_in = cur_addr->ats_addr->assigned_bw_in;
207 log_a->assigned_bw_out = cur_addr->ats_addr->assigned_bw_out;
208 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
209 {
210 log_a->prop_abs[c] = cur_addr->prop_abs[c];
211 log_a->prop_norm[c] = cur_addr->prop_norm[c];
212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
213 "\t %s = %.2f %.2f [abs/rel]\n",
214 GNUNET_ATS_print_property_type (c),
215 log_a->prop_abs[c],
216 log_a->prop_norm[c]);
217 }
218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
219 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n",
220 log_a->assigned_bw_in);
221 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "\t BW out = %llu\n",
222 log_a->assigned_bw_out);
223
224 GNUNET_CONTAINER_DLL_insert_tail (log_p->addr_head, log_p->addr_tail,
225 log_a);
226 }
227 }
228}
229
230
231static void
232logging_task (void *cls)
233{
234 struct LoggingHandle *l = cls;
235
236 l->logging_task = NULL;
237 GNUNET_ATS_solver_logging_now (l);
238 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq,
239 &logging_task,
240 l);
241}
242
243
244struct LoggingHandle *
245GNUNET_ATS_solver_logging_start (struct GNUNET_TIME_Relative freq)
246{
247 struct LoggingHandle *l;
248
249 l = GNUNET_new (struct LoggingHandle);
250
251 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start logging every %s\n",
252 GNUNET_STRINGS_relative_time_to_string (freq, GNUNET_NO));
253 l->log_freq = freq;
254 l->logging_task = GNUNET_SCHEDULER_add_now (&logging_task, l);
255 return l;
256}
257
258
259void
260GNUNET_ATS_solver_logging_stop (struct LoggingHandle *l)
261{
262 if (NULL != l->logging_task)
263 GNUNET_SCHEDULER_cancel (l->logging_task);
264
265 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stop logging\n");
266
267 l->logging_task = NULL;
268}
269
270
271static struct LoggingFileHandle *
272find_logging_file_handle (struct LoggingFileHandle *lf_head,
273 struct LoggingFileHandle *lf_tail,
274 int peer_id, int address_id)
275{
276 struct LoggingFileHandle *res;
277
278 for (res = lf_head; NULL != res; res = res->next)
279 if ((res->pid == peer_id) && (res->aid == address_id))
280 return res;
281 return NULL;
282}
283
284
285void
286GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int
287 add_time_stamp,
288 char *output_dir)
289{
290 struct LoggingTimeStep *lts;
291 struct LoggingPeer *log_p;
292 struct LoggingAddress *log_a;
293 struct LoggingFileHandle *lf_head;
294 struct LoggingFileHandle *lf_tail;
295 struct LoggingFileHandle *cur;
296 struct LoggingFileHandle *next;
297 char *filename;
298 char *datastring;
299 char *propstring;
300 char *propstring_tmp;
301 char *prefstring;
302 char *prefstring_tmp;
303 int c;
304 int use_dir;
305
306 use_dir = GNUNET_NO;
307 if (NULL != output_dir)
308 {
309 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (output_dir))
310 {
311 fprintf (stderr, "Failed to create directory `%s'\n", output_dir);
312 return;
313 }
314 else
315 {
316 fprintf (stderr, "Created directory `%s'\n", output_dir);
317 use_dir = GNUNET_YES;
318 }
319 }
320
321 lf_head = NULL;
322 lf_tail = NULL;
323
324 for (lts = l->head; NULL != lts; lts = lts->next)
325 {
326 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing log step %llu\n",
327 (long long unsigned int) lts->timestamp.abs_value_us);
328
329 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
330 {
331 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
332 {
333 cur = find_logging_file_handle (lf_head, lf_tail, log_p->id,
334 log_a->aid);
335 if (NULL == cur)
336 {
337 cur = GNUNET_new (struct LoggingFileHandle);
338 cur->aid = log_a->aid;
339 cur->pid = log_p->id;
340
341 if (GNUNET_YES == add_time_stamp)
342 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u_%llu.log",
343 (GNUNET_YES == use_dir) ? output_dir : "",
344 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
345 e->log_prefix,
346 opt_solver,
347 cur->pid,
348 cur->aid,
349 l->head->timestamp.abs_value_us);
350 else
351 GNUNET_asprintf (&filename, "%s%s%s_%s_p%u_a%u.log",
352 (GNUNET_YES == use_dir) ? output_dir : "",
353 (GNUNET_YES == use_dir) ? DIR_SEPARATOR_STR : "",
354 e->log_prefix,
355 opt_solver,
356 cur->pid,
357 cur->aid);
358
359 fprintf (stderr,
360 "Add writing log data for peer %llu address %llu to file `%s'\n",
361 cur->pid, cur->aid, filename);
362
363
364 cur->f_hd = GNUNET_DISK_file_open (filename,
365 GNUNET_DISK_OPEN_READWRITE
366 | GNUNET_DISK_OPEN_CREATE
367 | GNUNET_DISK_OPEN_TRUNCATE,
368 GNUNET_DISK_PERM_USER_READ
369 | GNUNET_DISK_PERM_USER_WRITE
370 | GNUNET_DISK_PERM_GROUP_READ
371 | GNUNET_DISK_PERM_OTHER_READ);
372 if (NULL == cur->f_hd)
373 {
374 fprintf (stderr, "Cannot open `%s' to write log data!\n", filename);
375 GNUNET_free (filename);
376 GNUNET_free (cur);
377 goto cleanup;
378 }
379 GNUNET_free (filename);
380 GNUNET_CONTAINER_DLL_insert (lf_head, lf_tail, cur);
381
382 GNUNET_asprintf (&datastring,
383 "#time delta;log duration;peer_requested;addr net; addr_active; bw in; bw out; " \
384 "UTILIZATION_UP [abs/rel]; UTILIZATION_UP; UTILIZATION_DOWN; UTILIZATION_DOWN; " \
385 "UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_UP; UTILIZATION_PAYLOAD_DOWN; UTILIZATION_PAYLOAD_DOWN;" \
386 "DELAY; DELAY; " \
387 "DISTANCE ;DISTANCE ; COST_WAN; COST_WAN; COST_LAN; COST_LAN; " \
388 "COST_WLAN; COST_WLAN;COST_BT; COST_BT; PREF BW abs; PREF BW rel; PREF LATENCY abs; PREF LATENCY rel;\n");
389 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen (datastring));
390 GNUNET_free (datastring);
391 }
392
393 prefstring = GNUNET_strdup ("");
394 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
395 {
396 /*
397 fprintf(stderr,"\t %s = %.2f %.2f [abs/rel]\n",
398 GNUNET_ATS_print_preference_type(c),
399 log_p->pref_abs[c], log_p->pref_norm[c]);
400 */GNUNET_asprintf (&prefstring_tmp, "%s;%.3f;%.3f",
401 prefstring, log_p->pref_abs[c], log_p->pref_norm[c]);
402
403
404 GNUNET_free (prefstring);
405 prefstring = GNUNET_strdup (prefstring_tmp);
406 GNUNET_free (prefstring_tmp);
407 }
408
409
410 propstring = GNUNET_strdup ("");
411 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
412 {
413 if (GNUNET_ATS_NETWORK_TYPE == c)
414 continue;
415 /*
416 fprintf(stderr, "\t %s = %.2f %.2f [abs/rel]\n",
417 GNUNET_ATS_print_property_type(c),
418 log_a->prop_abs[c], log_a->prop_norm[c]);*/
419 GNUNET_asprintf (&propstring_tmp, "%s%.3f;%.3f;",
420 propstring,
421 log_a->prop_abs[c],
422 log_a->prop_norm[c]);
423 GNUNET_free (propstring);
424 propstring = GNUNET_strdup (propstring_tmp);
425 GNUNET_free (propstring_tmp);
426 }
427 GNUNET_asprintf (&datastring, "%llu;%llu;%u;%u;%i;%u;%u;%s;%s\n",
428 GNUNET_TIME_absolute_get_difference (
429 l->head->timestamp,
430 lts->timestamp).
431 rel_value_us / 1000, lts->delta,
432 log_p->is_requested, log_a->network, log_a->active,
433 log_a->assigned_bw_in, log_a->assigned_bw_out,
434 propstring,
435 prefstring);
436
437 GNUNET_DISK_file_write (cur->f_hd, datastring, strlen (datastring));
438 GNUNET_free (datastring);
439 GNUNET_free (prefstring);
440 GNUNET_free (propstring);
441 }
442 }
443 }
444
445 cleanup:
446 next = lf_head;
447 for (cur = next; NULL != cur; cur = next)
448 {
449 next = cur->next;
450 GNUNET_CONTAINER_DLL_remove (lf_head, lf_tail, cur);
451 if (NULL != cur->f_hd)
452 GNUNET_DISK_file_close (cur->f_hd);
453 GNUNET_free (cur);
454 }
455}
456
457
458void
459GNUNET_ATS_solver_logging_eval (struct LoggingHandle *l)
460{
461 struct LoggingTimeStep *lts;
462 struct LoggingPeer *log_p;
463 struct LoggingAddress *log_a;
464 int c;
465
466 for (lts = l->head; NULL != lts; lts = lts->next)
467 {
468 fprintf (stderr, "Log step %llu %llu: \n",
469 (long long unsigned int) lts->timestamp.abs_value_us,
470 (long long unsigned int) lts->delta.rel_value_us);
471
472 for (log_p = lts->head; NULL != log_p; log_p = log_p->next)
473 {
474 fprintf (stderr, "\tLogging peer pid %llu\n", log_p->id);
475 for (c = 1; c < GNUNET_ATS_PreferenceCount; c++)
476 {
477 fprintf (stderr, "\t %s = %.2f %.2f [abs/rel]\n",
478 GNUNET_ATS_print_preference_type (c),
479 log_p->pref_abs[c], log_p->pref_norm[c]);
480 }
481
482 for (log_a = log_p->addr_head; NULL != log_a; log_a = log_a->next)
483 {
484 fprintf (stderr, "\tPeer pid %llu address %llu: %u %u %u\n",
485 log_p->id, log_a->aid, log_a->active,
486 log_a->assigned_bw_in,
487 log_a->assigned_bw_out);
488
489 for (c = 1; c < GNUNET_ATS_PropertyCount; c++)
490 {
491 if (GNUNET_ATS_NETWORK_TYPE == c)
492 continue;
493 fprintf (stderr, "\t %s = %.2f %.2f [abs/rel]\n",
494 GNUNET_ATS_print_property_type (c),
495 log_a->prop_abs[c], log_a->prop_norm[c]);
496 }
497 }
498 }
499 }
500}
501
502
503void
504GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
505{
506 struct LoggingTimeStep *lts_cur;
507 struct LoggingTimeStep *lts_next;
508 struct LoggingPeer *log_p_cur;
509 struct LoggingPeer *log_p_next;
510 struct LoggingAddress *log_a_cur;
511 struct LoggingAddress *log_a_next;
512
513 if (NULL != l->logging_task)
514 GNUNET_SCHEDULER_cancel (l->logging_task);
515 l->logging_task = NULL;
516
517 lts_next = l->head;
518 while (NULL != (lts_cur = lts_next))
519 {
520 lts_next = lts_cur->next;
521
522 log_p_next = lts_cur->head;
523 while (NULL != (log_p_cur = log_p_next))
524 {
525 log_p_next = log_p_cur->next;
526
527 log_a_next = log_p_cur->addr_head;
528 while (NULL != (log_a_cur = log_a_next))
529 {
530 log_a_next = log_a_cur->next;
531
532 GNUNET_CONTAINER_DLL_remove (log_p_cur->addr_head, log_p_cur->addr_tail,
533 log_a_cur);
534 GNUNET_free (log_a_cur);
535 }
536
537 GNUNET_CONTAINER_DLL_remove (lts_cur->head, lts_cur->tail, log_p_cur);
538 GNUNET_free (log_p_cur);
539 }
540
541 GNUNET_CONTAINER_DLL_remove (l->head, l->tail, lts_cur);
542 GNUNET_free (lts_cur);
543 }
544
545 GNUNET_free (l);
546}
547
548
549/**
550 * Property Generators
551 */
552static struct PropertyGenerator *prop_gen_head;
553static struct PropertyGenerator *prop_gen_tail;
554
555
556static double
557get_property (struct PropertyGenerator *pg)
558{
559 struct GNUNET_TIME_Relative time_delta;
560 double delta_value;
561 double pref_value;
562
563 /* Calculate the current preference value */
564 switch (pg->type)
565 {
566 case GNUNET_ATS_TEST_TG_CONSTANT:
567 pref_value = pg->base_value;
568 break;
569
570 case GNUNET_ATS_TEST_TG_LINEAR:
571 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
572 /* Calculate point of time in the current period */
573 time_delta.rel_value_us = time_delta.rel_value_us
574 % pg->duration_period.rel_value_us;
575 delta_value = ((double) time_delta.rel_value_us
576 / pg->duration_period.rel_value_us) * (pg->max_value
577 - pg->base_value);
578 if ((pg->max_value < pg->base_value) &&
579 ((pg->max_value - pg->base_value) > pg->base_value))
580 {
581 /* This will cause an underflow */
582 GNUNET_break (0);
583 }
584 pref_value = pg->base_value + delta_value;
585 break;
586
587 case GNUNET_ATS_TEST_TG_RANDOM:
588 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
589 10000 * (pg->max_value
590 - pg->base_value))
591 / 10000;
592 pref_value = pg->base_value + delta_value;
593 break;
594
595 case GNUNET_ATS_TEST_TG_SINUS:
596 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
597 /* Calculate point of time in the current period */
598 time_delta.rel_value_us = time_delta.rel_value_us
599 % pg->duration_period.rel_value_us;
600 if ((pg->max_value - pg->base_value) > pg->base_value)
601 {
602 /* This will cause an underflow for second half of sinus period,
603 * will be detected in general when experiments are loaded */
604 GNUNET_break (0);
605 }
606 delta_value = (pg->max_value - pg->base_value)
607 * sin ((2 * M_PI)
608 / ((double) pg->duration_period.rel_value_us)
609 * time_delta.rel_value_us);
610 pref_value = pg->base_value + delta_value;
611 break;
612
613 default:
614 pref_value = 0.0;
615 break;
616 }
617 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current property value is %f\n",
618 pref_value);
619 return pref_value;
620}
621
622
623static void
624set_prop_task (void *cls)
625{
626 struct PropertyGenerator *pg = cls;
627 struct TestPeer *p;
628 struct TestAddress *a;
629 double prop_value;
630 struct GNUNET_ATS_Information atsi;
631
632 pg->set_task = NULL;
633
634 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains_value (sh->addresses,
635 &pg->test_peer
636 ->peer_id,
637 pg->
638 test_address->
639 ats_addr))
640 {
641 GNUNET_break (0);
642 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
643 "Setting property generation for unknown address [%u:%u]\n",
644 pg->peer, pg->address_id);
645 return;
646 }
647 if (NULL == (p = find_peer_by_id (pg->peer)))
648 {
649 GNUNET_break (0);
650 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
651 "Setting property generation for unknown peer %u\n",
652 pg->peer);
653 return;
654 }
655 if (NULL == (a = find_address_by_id (p, pg->address_id)))
656 {
657 GNUNET_break (0);
658 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
659 "Setting property generation for unknown peer %u\n",
660 pg->peer);
661 return;
662 }
663
664 prop_value = get_property (pg);
665 a->prop_abs[pg->ats_property] = prop_value;
666
667 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
668 "Setting property for peer [%u] address [%u] for %s to %f\n",
669 pg->peer, pg->address_id,
670 GNUNET_ATS_print_property_type (pg->ats_property), prop_value);
671
672 atsi.type = htonl (pg->ats_property);
673 atsi.value = htonl ((uint32_t) prop_value);
674
675 /* set performance here! */
676 sh->sf->s_bulk_start (sh->sf->cls);
677 if (GNUNET_YES == opt_disable_normalization)
678 {
679 a->prop_abs[pg->ats_property] = prop_value;
680 a->prop_norm[pg->ats_property] = prop_value;
681 sh->sf->s_address_update_property (sh->sf->cls, a->ats_addr,
682 pg->ats_property, prop_value,
683 prop_value);
684 }
685 else
686 GAS_normalization_update_property (pg->test_address->ats_addr, &atsi, 1);
687 sh->sf->s_bulk_stop (sh->sf->cls);
688
689 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
690 &set_prop_task, pg);
691}
692
693
694/**
695 * Set ats_property to 0 to find all pgs
696 */
697static struct PropertyGenerator *
698find_prop_gen (unsigned int peer, unsigned int address,
699 uint32_t ats_property)
700{
701 struct PropertyGenerator *cur;
702
703 for (cur = prop_gen_head; NULL != cur; cur = cur->next)
704 if ((cur->peer == peer) && (cur->address_id == address))
705 {
706 if ((cur->ats_property == ats_property) || (0 == ats_property))
707 return cur;
708 }
709 return NULL;
710}
711
712
713void
714GNUNET_ATS_solver_generate_property_stop (struct PropertyGenerator *pg)
715{
716 GNUNET_CONTAINER_DLL_remove (prop_gen_head, prop_gen_tail, pg);
717
718 if (NULL != pg->set_task)
719 {
720 GNUNET_SCHEDULER_cancel (pg->set_task);
721 pg->set_task = NULL;
722 }
723 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
724 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
725 pg->peer, pg->address_id,
726 GNUNET_ATS_print_property_type (pg->ats_property));
727
728 GNUNET_free (pg);
729}
730
731
732/**
733 * Generate between the source master and the partner and set property with a
734 * value depending on the generator.
735 *
736 * @param peer source
737 * @param address_id partner
738 * @param test_peer the peer
739 * @param test_address the address
740 * @param type type of generator
741 * @param base_value base value
742 * @param value_rate maximum value
743 * @param period duration of a period of generation (~ 1/frequency)
744 * @param frequency how long to generate property
745 * @param ats_property ATS property to generate
746 * @return the property generator
747 */
748struct PropertyGenerator *
749GNUNET_ATS_solver_generate_property_start (unsigned int peer,
750 unsigned int address_id,
751 struct TestPeer *test_peer,
752 struct TestAddress *test_address,
753 enum GeneratorType type,
754 long int base_value,
755 long int value_rate,
756 struct GNUNET_TIME_Relative period,
757 struct GNUNET_TIME_Relative
758 frequency,
759 uint32_t ats_property)
760{
761 struct PropertyGenerator *pg;
762
763 pg = GNUNET_new (struct PropertyGenerator);
764 GNUNET_CONTAINER_DLL_insert (prop_gen_head, prop_gen_tail, pg);
765 pg->type = type;
766 pg->peer = peer;
767 pg->test_address = test_address;
768 pg->test_peer = test_peer;
769 pg->address_id = address_id;
770 pg->ats_property = ats_property;
771 pg->base_value = base_value;
772 pg->max_value = value_rate;
773 pg->duration_period = period;
774 pg->frequency = frequency;
775 pg->time_start = GNUNET_TIME_absolute_get ();
776
777 switch (type)
778 {
779 case GNUNET_ATS_TEST_TG_CONSTANT:
780 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
781 "Setting up %s property generator peer [%u] address [%u] `%s'" \
782 "max %u Bips\n",
783 print_generator_type (type), pg->peer, pg->address_id,
784 GNUNET_ATS_print_property_type (ats_property),
785 base_value);
786 break;
787
788 case GNUNET_ATS_TEST_TG_LINEAR:
789 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
790 "Setting up %s property generator peer [%u] address [%u] `%s' " \
791 "min %u Bips max %u Bips\n",
792 print_generator_type (type), pg->peer, pg->address_id,
793 GNUNET_ATS_print_property_type (ats_property),
794 base_value, value_rate);
795 break;
796
797 case GNUNET_ATS_TEST_TG_SINUS:
798 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
799 "Setting up %s property generator peer [%u] address [%u] `%s' " \
800 "baserate %u Bips, amplitude %u Bps\n",
801 print_generator_type (type), pg->peer, pg->address_id,
802 GNUNET_ATS_print_property_type (ats_property),
803 base_value, value_rate);
804 break;
805
806 case GNUNET_ATS_TEST_TG_RANDOM:
807 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
808 "Setting up %s property generator peer [%u] address [%u] `%s' " \
809 "min %u Bips max %u Bps\n",
810 print_generator_type (type), pg->peer, pg->address_id,
811 GNUNET_ATS_print_property_type (ats_property),
812 base_value, value_rate);
813 break;
814
815 default:
816 break;
817 }
818
819 pg->set_task = GNUNET_SCHEDULER_add_now (&set_prop_task, pg);
820 return pg;
821}
822
823
824/**
825 * Stop all preferences generators
826 */
827void
828GNUNET_ATS_solver_generate_property_stop_all ()
829{
830 struct PropertyGenerator *cur;
831 struct PropertyGenerator *next;
832
833 next = prop_gen_head;
834 for (cur = next; NULL != cur; cur = next)
835 {
836 next = cur->next;
837 GNUNET_ATS_solver_generate_property_stop (cur);
838 }
839}
840
841
842/**
843 * Preference Generators
844 */
845static struct PreferenceGenerator *pref_gen_head;
846static struct PreferenceGenerator *pref_gen_tail;
847
848
849static double
850get_preference (struct PreferenceGenerator *pg)
851{
852 struct GNUNET_TIME_Relative time_delta;
853 double delta_value;
854 double pref_value;
855
856 /* Calculate the current preference value */
857 switch (pg->type)
858 {
859 case GNUNET_ATS_TEST_TG_CONSTANT:
860 pref_value = pg->base_value;
861 break;
862
863 case GNUNET_ATS_TEST_TG_LINEAR:
864 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
865 /* Calculate point of time in the current period */
866 time_delta.rel_value_us = time_delta.rel_value_us
867 % pg->duration_period.rel_value_us;
868 delta_value = ((double) time_delta.rel_value_us
869 / pg->duration_period.rel_value_us) * (pg->max_value
870 - pg->base_value);
871 if ((pg->max_value < pg->base_value) &&
872 ((pg->max_value - pg->base_value) > pg->base_value))
873 {
874 /* This will cause an underflow */
875 GNUNET_break (0);
876 }
877 pref_value = pg->base_value + delta_value;
878 break;
879
880 case GNUNET_ATS_TEST_TG_RANDOM:
881 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
882 10000 * (pg->max_value
883 - pg->base_value))
884 / 10000;
885 pref_value = pg->base_value + delta_value;
886 break;
887
888 case GNUNET_ATS_TEST_TG_SINUS:
889 time_delta = GNUNET_TIME_absolute_get_duration (pg->time_start);
890 /* Calculate point of time in the current period */
891 time_delta.rel_value_us = time_delta.rel_value_us
892 % pg->duration_period.rel_value_us;
893 if ((pg->max_value - pg->base_value) > pg->base_value)
894 {
895 /* This will cause an underflow for second half of sinus period,
896 * will be detected in general when experiments are loaded */
897 GNUNET_break (0);
898 }
899 delta_value = (pg->max_value - pg->base_value)
900 * sin ((2 * M_PI)
901 / ((double) pg->duration_period.rel_value_us)
902 * time_delta.rel_value_us);
903 pref_value = pg->base_value + delta_value;
904 break;
905
906 default:
907 pref_value = 0.0;
908 break;
909 }
910 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
911 pref_value);
912 return pref_value;
913}
914
915
916static void
917set_feedback_task (void *cls)
918{
919 struct PreferenceGenerator *pg = cls;
920 struct TestPeer *p;
921 double feedback;
922 uint32_t bw_acc_out;
923 uint32_t bw_acc_in;
924 uint32_t delay_acc_in;
925 struct GNUNET_TIME_Relative dur;
926 double p_new;
927
928 pg->feedback_task = NULL;
929
930 if (NULL == (p = find_peer_by_id (pg->peer)))
931 {
932 GNUNET_break (0);
933 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
934 "Setting feedback for unknown peer %u\n", pg->peer);
935 return;
936 }
937
938 switch (pg->kind)
939 {
940 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
941 dur = GNUNET_TIME_absolute_get_duration (pg->feedback_last_bw_update);
942 bw_acc_in = dur.rel_value_us * pg->last_assigned_bw_in
943 + pg->feedback_bw_in_acc;
944 pg->feedback_bw_in_acc = 0;
945
946 bw_acc_out = dur.rel_value_us * pg->last_assigned_bw_out
947 + pg->feedback_bw_out_acc;
948 p_new = get_preference (pg);
949 feedback = (p_new / pg->pref_bw_old) * (bw_acc_in + bw_acc_out)
950 / (2 * GNUNET_TIME_absolute_get_duration (
951 pg->feedback_last).rel_value_us);
952
953 break;
954
955 case GNUNET_ATS_PREFERENCE_LATENCY:
956 dur = GNUNET_TIME_absolute_get_duration (pg->feedback_last_delay_update);
957 delay_acc_in = dur.rel_value_us * pg->last_delay_value
958 + pg->feedback_delay_acc;
959 pg->feedback_delay_acc = 0;
960
961 p_new = get_preference (pg);
962 feedback = (p_new / pg->pref_latency_old) * (delay_acc_in)
963 / (GNUNET_TIME_absolute_get_duration (
964 pg->feedback_last).rel_value_us);
965
966 break;
967
968 default:
969 GNUNET_break (0);
970 feedback = 0.0;
971 break;
972 }
973 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
974 "Giving feedback for peer [%u] for client %p pref %s of %.3f\n",
975 pg->peer, NULL + (pg->client_id),
976 GNUNET_ATS_print_preference_type (pg->kind),
977 feedback);
978
979 sh->sf->s_feedback (sh->sf->cls, NULL + (pg->client_id), &p->peer_id,
980 pg->feedback_frequency, pg->kind, feedback);
981 pg->feedback_last = GNUNET_TIME_absolute_get ();
982
983
984 pg->feedback_bw_out_acc = 0;
985 pg->feedback_bw_in_acc = 0;
986 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get ();
987
988 pg->feedback_delay_acc = 0;
989 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get ();
990
991
992 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (pg->feedback_frequency,
993 &set_feedback_task, pg);
994}
995
996
997static void
998set_pref_task (void *cls)
999{
1000 struct PreferenceGenerator *pg = cls;
1001 struct TestPeer *p;
1002 double pref_value;
1003
1004 pg->set_task = NULL;
1005
1006 if (NULL == (p = find_peer_by_id (pg->peer)))
1007 {
1008 GNUNET_break (0);
1009 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1010 "Setting preference for unknown peer %u\n", pg->peer);
1011 return;
1012 }
1013
1014 pref_value = get_preference (pg);
1015 switch (pg->kind)
1016 {
1017 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
1018 pg->pref_bw_old = pref_value;
1019 break;
1020
1021 case GNUNET_ATS_PREFERENCE_LATENCY:
1022 pg->pref_latency_old = pref_value;
1023 break;
1024
1025 default:
1026 break;
1027 }
1028
1029 p->pref_abs[pg->kind] = pref_value;
1030
1031 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1032 "Setting preference for peer [%u] for client %p pref %s to %f\n",
1033 pg->peer, NULL + (pg->client_id),
1034 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
1035
1036 if (GNUNET_YES == opt_disable_normalization)
1037 {
1038 p->pref_abs[pg->kind] = pref_value;
1039 p->pref_norm[pg->kind] = pref_value;
1040 sh->sf->s_pref (sh->sf->cls, &p->peer_id, pg->kind, pref_value);
1041 }
1042 else
1043 update_preference (NULL + (pg->client_id),
1044 &p->peer_id,
1045 pg->kind,
1046 pref_value);
1047
1048 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
1049 &set_pref_task,
1050 pg);
1051}
1052
1053
1054static struct PreferenceGenerator *
1055find_pref_gen (unsigned int peer, enum GNUNET_ATS_PreferenceKind kind)
1056{
1057 struct PreferenceGenerator *cur;
1058
1059 for (cur = pref_gen_head; NULL != cur; cur = cur->next)
1060 if (cur->peer == peer)
1061 {
1062 if ((cur->kind == kind) || (GNUNET_ATS_PREFERENCE_END == kind))
1063 return cur;
1064 }
1065 return NULL;
1066}
1067
1068
1069void
1070GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
1071{
1072 GNUNET_CONTAINER_DLL_remove (pref_gen_head, pref_gen_tail, pg);
1073
1074 if (NULL != pg->feedback_task)
1075 {
1076 GNUNET_SCHEDULER_cancel (pg->feedback_task);
1077 pg->feedback_task = NULL;
1078 }
1079
1080 if (NULL != pg->set_task)
1081 {
1082 GNUNET_SCHEDULER_cancel (pg->set_task);
1083 pg->set_task = NULL;
1084 }
1085 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1086 "Removing old up preference generator peer [%u] `%s'\n",
1087 pg->peer, GNUNET_ATS_print_preference_type (pg->kind));
1088
1089 GNUNET_free (pg);
1090}
1091
1092
1093static struct TestAddress*
1094find_active_address (struct TestPeer *p)
1095{
1096 struct TestAddress *cur;
1097
1098 for (cur = p->addr_head; NULL != cur; cur = cur->next)
1099 if (GNUNET_YES == cur->ats_addr->active)
1100 return cur;
1101 return NULL;
1102}
1103
1104
1105/**
1106 * Generate between the source master and the partner and set property with a
1107 * value depending on the generator.
1108 *
1109 * @param peer source
1110 * @param address_id partner
1111 * @param client_id the client
1112 * @param type type of generator
1113 * @param base_value base value
1114 * @param value_rate maximum value
1115 * @param period duration of a period of generation (~ 1/frequency)
1116 * @param frequency how long to generate property
1117 * @param kind ATS preference to generate
1118 * @param feedback_frequency how often to give feedback
1119 * @return the preference generator
1120 */
1121struct PreferenceGenerator *
1122GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
1123 unsigned int address_id,
1124 unsigned int client_id,
1125 enum GeneratorType type,
1126 long int base_value,
1127 long int value_rate,
1128 struct GNUNET_TIME_Relative
1129 period,
1130 struct GNUNET_TIME_Relative
1131 frequency,
1132 enum GNUNET_ATS_PreferenceKind
1133 kind,
1134 struct GNUNET_TIME_Relative
1135 feedback_frequency)
1136{
1137 struct PreferenceGenerator *pg;
1138 struct TestPeer *p;
1139
1140 if (NULL == (p = find_peer_by_id (peer)))
1141 {
1142 GNUNET_break (0);
1143 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1144 "Starting preference for unknown peer %u\n", peer);
1145 return NULL;
1146 }
1147
1148 pg = GNUNET_new (struct PreferenceGenerator);
1149 GNUNET_CONTAINER_DLL_insert (pref_gen_head, pref_gen_tail, pg);
1150 pg->type = type;
1151 pg->peer = peer;
1152 pg->client_id = client_id;
1153 pg->kind = kind;
1154 pg->base_value = base_value;
1155 pg->max_value = value_rate;
1156 pg->duration_period = period;
1157 pg->frequency = frequency;
1158 pg->time_start = GNUNET_TIME_absolute_get ();
1159 pg->feedback_frequency = feedback_frequency;
1160
1161 switch (type)
1162 {
1163 case GNUNET_ATS_TEST_TG_CONSTANT:
1164 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1165 "Setting up %s preference generator peer [%u] `%s' max %u Bips\n",
1166 print_generator_type (type), pg->peer,
1167 GNUNET_ATS_print_preference_type (kind),
1168 base_value);
1169 break;
1170
1171 case GNUNET_ATS_TEST_TG_LINEAR:
1172 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1173 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bips\n",
1174 print_generator_type (type), pg->peer,
1175 GNUNET_ATS_print_preference_type (kind),
1176 base_value, value_rate);
1177 break;
1178
1179 case GNUNET_ATS_TEST_TG_SINUS:
1180 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1181 "Setting up %s preference generator peer [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
1182 print_generator_type (type), pg->peer,
1183 GNUNET_ATS_print_preference_type (kind),
1184 base_value, value_rate);
1185 break;
1186
1187 case GNUNET_ATS_TEST_TG_RANDOM:
1188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1189 "Setting up %s preference generator peer [%u] `%s' min %u Bips max %u Bps\n",
1190 print_generator_type (type), pg->peer,
1191 GNUNET_ATS_print_preference_type (kind),
1192 base_value, value_rate);
1193 break;
1194
1195 default:
1196 break;
1197 }
1198
1199 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
1200 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us !=
1201 feedback_frequency.rel_value_us)
1202 {
1203 struct TestAddress *addr = find_active_address (p);
1204
1205 pg->last_assigned_bw_in = p->assigned_bw_in;
1206 pg->last_assigned_bw_out = p->assigned_bw_out;
1207 pg->feedback_bw_in_acc = 0;
1208 pg->feedback_bw_out_acc = 0;
1209 pg->last_delay_value = addr->prop_norm[GNUNET_ATS_QUALITY_NET_DELAY];
1210 pg->feedback_delay_acc = 0;
1211
1212 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get ();
1213 pg->feedback_last_delay_update = GNUNET_TIME_absolute_get ();
1214 pg->feedback_last = GNUNET_TIME_absolute_get ();
1215 pg->feedback_task = GNUNET_SCHEDULER_add_delayed (feedback_frequency,
1216 &set_feedback_task, pg);
1217 }
1218
1219 return pg;
1220}
1221
1222
1223/**
1224 * Stop all preferences generators
1225 */
1226void
1227GNUNET_ATS_solver_generate_preferences_stop_all ()
1228{
1229 struct PreferenceGenerator *cur;
1230 struct PreferenceGenerator *next;
1231
1232 next = pref_gen_head;
1233 for (cur = next; NULL != cur; cur = next)
1234 {
1235 next = cur->next;
1236 GNUNET_ATS_solver_generate_preferences_stop (cur);
1237 }
1238}
1239
1240
1241/**
1242 * Experiments
1243 */
1244static const char *
1245print_op (enum OperationType op)
1246{
1247 switch (op)
1248 {
1249 case SOLVER_OP_ADD_ADDRESS:
1250 return "ADD_ADDRESS";
1251
1252 case SOLVER_OP_DEL_ADDRESS:
1253 return "DEL_ADDRESS";
1254
1255 case SOLVER_OP_START_SET_PREFERENCE:
1256 return "START_SET_PREFERENCE";
1257
1258 case SOLVER_OP_STOP_SET_PREFERENCE:
1259 return "STOP_STOP_PREFERENCE";
1260
1261 case SOLVER_OP_START_SET_PROPERTY:
1262 return "START_SET_PROPERTY";
1263
1264 case SOLVER_OP_STOP_SET_PROPERTY:
1265 return "STOP_SET_PROPERTY";
1266
1267 case SOLVER_OP_START_REQUEST:
1268 return "START_REQUEST";
1269
1270 case SOLVER_OP_STOP_REQUEST:
1271 return "STOP_REQUEST";
1272
1273 default:
1274 break;
1275 }
1276 return "";
1277}
1278
1279
1280static struct Experiment *
1281create_experiment ()
1282{
1283 struct Experiment *e;
1284
1285 e = GNUNET_new (struct Experiment);
1286 e->name = NULL;
1287 e->start = NULL;
1288 e->total_duration = GNUNET_TIME_UNIT_ZERO;
1289 return e;
1290}
1291
1292
1293static void
1294free_experiment (struct Experiment *e)
1295{
1296 struct Episode *cur;
1297 struct Episode *next;
1298 struct GNUNET_ATS_TEST_Operation *cur_o;
1299 struct GNUNET_ATS_TEST_Operation *next_o;
1300
1301 next = e->start;
1302 for (cur = next; NULL != cur; cur = next)
1303 {
1304 next = cur->next;
1305
1306 next_o = cur->head;
1307 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
1308 {
1309 next_o = cur_o->next;
1310 GNUNET_free (cur_o->address);
1311 GNUNET_free (cur_o->plugin);
1312 GNUNET_free (cur_o);
1313 }
1314 GNUNET_free (cur);
1315 }
1316
1317 GNUNET_free (e->name);
1318 GNUNET_free (e->log_prefix);
1319 GNUNET_free (e->log_output_dir);
1320 GNUNET_free (e->cfg_file);
1321 GNUNET_free (e);
1322}
1323
1324
1325static int
1326load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
1327 struct Episode *e,
1328 int op_counter,
1329 char *sec_name,
1330 const struct GNUNET_CONFIGURATION_Handle *cfg)
1331{
1332 char *op_name;
1333 char *op_network;
1334
1335 /* peer pid */
1336 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1337 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1338 sec_name, op_name,
1339 &o->peer_id))
1340 {
1341 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1342 op_counter, "ADD_ADDRESS", op_name);
1343 GNUNET_free (op_name);
1344 return GNUNET_SYSERR;
1345 }
1346 GNUNET_free (op_name);
1347
1348 /* address pid */
1349 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1350 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1351 sec_name, op_name,
1352 &o->address_id))
1353 {
1354 fprintf (stderr,
1355 "Missing address-id in operation %u `%s' in episode `%s'\n",
1356 op_counter, "ADD_ADDRESS", op_name);
1357 GNUNET_free (op_name);
1358 return GNUNET_SYSERR;
1359 }
1360 GNUNET_free (op_name);
1361
1362 /* plugin */
1363 GNUNET_asprintf (&op_name, "op-%u-plugin", op_counter);
1364 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1365 sec_name, op_name,
1366 &o->plugin))
1367 {
1368 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1369 op_counter, "ADD_ADDRESS", op_name);
1370 GNUNET_free (op_name);
1371 return GNUNET_SYSERR;
1372 }
1373 GNUNET_free (op_name);
1374
1375 /* address */
1376 GNUNET_asprintf (&op_name, "op-%u-address", op_counter);
1377 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1378 sec_name, op_name,
1379 &o->address))
1380 {
1381 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1382 op_counter, "ADD_ADDRESS", op_name);
1383 GNUNET_free (op_name);
1384 return GNUNET_SYSERR;
1385 }
1386 GNUNET_free (op_name);
1387
1388 /* session */
1389 GNUNET_asprintf (&op_name, "op-%u-address-session", op_counter);
1390 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1391 sec_name, op_name,
1392 &o->
1393 address_session))
1394 {
1395 fprintf (stderr,
1396 "Missing address-session in operation %u `%s' in episode `%s'\n",
1397 op_counter, "ADD_ADDRESS", op_name);
1398 GNUNET_free (op_name);
1399 return GNUNET_SYSERR;
1400 }
1401 GNUNET_free (op_name);
1402
1403 /* network */
1404 GNUNET_asprintf (&op_name, "op-%u-address-network", op_counter);
1405 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1406 sec_name, op_name,
1407 &op_network))
1408 {
1409 fprintf (stderr,
1410 "Missing address-network in operation %u `%s' in episode `%s'\n",
1411 op_counter, "ADD_ADDRESS", op_name);
1412 GNUNET_free (op_name);
1413 return GNUNET_SYSERR;
1414 }
1415 else
1416 {
1417 GNUNET_break (GNUNET_OK == GNUNET_STRINGS_utf8_toupper (op_network,
1418 op_network));
1419 if (0 == strcmp (op_network, "UNSPECIFIED"))
1420 {
1421 o->address_network = GNUNET_NT_UNSPECIFIED;
1422 }
1423 else if (0 == strcmp (op_network, "LOOPBACK"))
1424 {
1425 o->address_network = GNUNET_NT_LOOPBACK;
1426 }
1427 else if (0 == strcmp (op_network, "LAN"))
1428 {
1429 o->address_network = GNUNET_NT_LAN;
1430 }
1431 else if (0 == strcmp (op_network, "WAN"))
1432 {
1433 o->address_network = GNUNET_NT_WAN;
1434 }
1435 else if (0 == strcmp (op_network, "WLAN"))
1436 {
1437 o->address_network = GNUNET_NT_WLAN;
1438 }
1439 else if (0 == strcmp (op_network, "BT"))
1440 {
1441 o->address_network = GNUNET_NT_BT;
1442 }
1443 else
1444 {
1445 fprintf (stderr,
1446 "Invalid address-network in operation %u `%s' in episode `%s': `%s'\n",
1447 op_counter, "ADD_ADDRESS", op_name, op_network);
1448 GNUNET_free (op_network);
1449 GNUNET_free (op_name);
1450 return GNUNET_SYSERR;
1451 }
1452 }
1453 GNUNET_free (op_network);
1454 GNUNET_free (op_name);
1455
1456 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1457 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1458 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1459
1460 return GNUNET_OK;
1461}
1462
1463
1464static int
1465load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
1466 struct Episode *e,
1467 int op_counter,
1468 char *sec_name,
1469 const struct GNUNET_CONFIGURATION_Handle *cfg)
1470{
1471 char *op_name;
1472
1473 // char *op_network;
1474
1475 /* peer pid */
1476 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1477 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1478 sec_name, op_name,
1479 &o->peer_id))
1480 {
1481 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1482 op_counter, "DEL_ADDRESS", op_name);
1483 GNUNET_free (op_name);
1484 return GNUNET_SYSERR;
1485 }
1486 GNUNET_free (op_name);
1487
1488 /* address pid */
1489 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1490 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1491 sec_name, op_name,
1492 &o->address_id))
1493 {
1494 fprintf (stderr,
1495 "Missing address-id in operation %u `%s' in episode `%s'\n",
1496 op_counter, "DEL_ADDRESS", op_name);
1497 GNUNET_free (op_name);
1498 return GNUNET_SYSERR;
1499 }
1500 GNUNET_free (op_name);
1501
1502#if 0
1503 /* plugin */
1504 GNUNET_asprintf (&op_name, "op-%u-plugin", op_counter);
1505 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1506 sec_name, op_name,
1507 &o->plugin))
1508 {
1509 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
1510 op_counter, "DEL_ADDRESS", op_name);
1511 GNUNET_free (op_name);
1512 return GNUNET_SYSERR;
1513 }
1514 GNUNET_free (op_name);
1515
1516 /* address */
1517 GNUNET_asprintf (&op_name, "op-%u-address", op_counter);
1518 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1519 sec_name, op_name,
1520 &o->address))
1521 {
1522 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
1523 op_counter, "DEL_ADDRESS", op_name);
1524 GNUNET_free (op_name);
1525 return GNUNET_SYSERR;
1526 }
1527 GNUNET_free (op_name);
1528
1529 /* session */
1530 GNUNET_asprintf (&op_name, "op-%u-address-session", op_counter);
1531 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1532 sec_name, op_name,
1533 &o->
1534 address_session))
1535 {
1536 fprintf (stderr,
1537 "Missing address-session in operation %u `%s' in episode `%s'\n",
1538 op_counter, "DEL_ADDRESS", op_name);
1539 GNUNET_free (op_name);
1540 return GNUNET_SYSERR;
1541 }
1542 GNUNET_free (op_name);
1543#endif
1544
1545 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1546 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
1547 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
1548
1549 return GNUNET_OK;
1550}
1551
1552
1553static enum GNUNET_ATS_Property
1554parse_preference_string (const char *str)
1555{
1556 int c = 0;
1557 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
1558
1559 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1560 if (0 == strcmp (str, props[c]))
1561 return c;
1562 return 0;
1563}
1564
1565
1566static int
1567load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1568 struct Episode *e,
1569 int op_counter,
1570 char *sec_name,
1571 const struct GNUNET_CONFIGURATION_Handle *cfg)
1572{
1573 char *op_name;
1574 char *type;
1575 char *pref;
1576
1577 /* peer pid */
1578 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1579 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1580 sec_name, op_name,
1581 &o->peer_id))
1582 {
1583 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1584 op_counter, "START_SET_PREFERENCE", op_name);
1585 GNUNET_free (op_name);
1586 return GNUNET_SYSERR;
1587 }
1588 GNUNET_free (op_name);
1589
1590 /* address pid */
1591 GNUNET_asprintf (&op_name, "op-%u-client-id", op_counter);
1592 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1593 sec_name, op_name,
1594 &o->client_id))
1595 {
1596 fprintf (stderr, "Missing client-id in operation %u `%s' in episode `%s'\n",
1597 op_counter, "START_SET_PREFERENCE", op_name);
1598 GNUNET_free (op_name);
1599 return GNUNET_SYSERR;
1600 }
1601 GNUNET_free (op_name);
1602
1603 /* generator */
1604 GNUNET_asprintf (&op_name, "op-%u-gen-type", op_counter);
1605 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1606 sec_name,
1607 op_name, &type)))
1608 {
1609 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1610 op_counter, "START_SET_PREFERENCE", op_name);
1611 GNUNET_free (op_name);
1612 return GNUNET_SYSERR;
1613 }
1614
1615 /* Load arguments for set_rate, start_send, set_preference */
1616 if (0 == strcmp (type, "constant"))
1617 {
1618 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1619 }
1620 else if (0 == strcmp (type, "linear"))
1621 {
1622 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1623 }
1624 else if (0 == strcmp (type, "sinus"))
1625 {
1626 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1627 }
1628 else if (0 == strcmp (type, "random"))
1629 {
1630 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1631 }
1632 else
1633 {
1634 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1635 op_counter, op_name, e->id);
1636 GNUNET_free (type);
1637 GNUNET_free (op_name);
1638 return GNUNET_SYSERR;
1639 }
1640 GNUNET_free (type);
1641 GNUNET_free (op_name);
1642
1643
1644 /* Get base rate */
1645 GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter);
1646 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1647 sec_name, op_name,
1648 &o->base_rate))
1649 {
1650 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1651 op_counter, op_name, e->id);
1652 GNUNET_free (op_name);
1653 return GNUNET_SYSERR;
1654 }
1655 GNUNET_free (op_name);
1656
1657
1658 /* Get max rate */
1659 GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter);
1660 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1661 sec_name, op_name,
1662 &o->max_rate))
1663 {
1664 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1665 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1666 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1667 {
1668 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1669 op_counter, op_name, e->id);
1670 GNUNET_free (op_name);
1671 return GNUNET_SYSERR;
1672 }
1673 }
1674 GNUNET_free (op_name);
1675
1676 /* Get period */
1677 GNUNET_asprintf (&op_name, "op-%u-period", op_counter);
1678 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1679 sec_name, op_name,
1680 &o->period))
1681 {
1682 o->period = e->duration;
1683 }
1684 GNUNET_free (op_name);
1685
1686 /* Get frequency */
1687 GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter);
1688 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1689 sec_name, op_name,
1690 &o->frequency))
1691 {
1692 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1693 op_counter, op_name, e->id);
1694 GNUNET_free (op_name);
1695 return GNUNET_SYSERR;
1696 }
1697 GNUNET_free (op_name);
1698
1699 /* Get preference */
1700 GNUNET_asprintf (&op_name, "op-%u-pref", op_counter);
1701 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1702 sec_name, op_name,
1703 &pref))
1704 {
1705 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1706 op_counter, op_name, e->id);
1707 GNUNET_free (op_name);
1708 return GNUNET_SYSERR;
1709 }
1710
1711 if (0 == (o->pref_type = parse_preference_string (pref)))
1712 {
1713 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1714 op_counter, op_name, e->id);
1715 GNUNET_free (op_name);
1716 GNUNET_free (pref);
1717 return GNUNET_SYSERR;
1718 }
1719 GNUNET_free (pref);
1720 GNUNET_free (op_name);
1721
1722 /* Get feedback delay */
1723 GNUNET_asprintf (&op_name, "op-%u-feedback_delay", op_counter);
1724 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg,
1725 sec_name, op_name,
1726 &o->feedback_delay))
1727 {
1728 fprintf (stderr,
1729 "Using feedback delay %llu in operation %u `%s' in episode %u\n",
1730 (long long unsigned int) o->feedback_delay.rel_value_us,
1731 op_counter, op_name, e->id);
1732 }
1733 else
1734 o->feedback_delay = GNUNET_TIME_UNIT_FOREVER_REL;
1735 GNUNET_free (op_name);
1736
1737 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1738 "Found operation %s: [%llu:%llu]: %s = %llu\n",
1739 "START_SET_PREFERENCE", o->peer_id, o->address_id,
1740 GNUNET_ATS_print_preference_type (o->pref_type), o->base_rate);
1741
1742 return GNUNET_OK;
1743}
1744
1745
1746static int
1747load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
1748 struct Episode *e,
1749 int op_counter,
1750 char *sec_name,
1751 const struct GNUNET_CONFIGURATION_Handle *cfg)
1752{
1753 char *op_name;
1754 char *pref;
1755
1756 /* peer pid */
1757 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1758 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1759 sec_name, op_name,
1760 &o->peer_id))
1761 {
1762 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1763 op_counter, "STOP_SET_PREFERENCE", op_name);
1764 GNUNET_free (op_name);
1765 return GNUNET_SYSERR;
1766 }
1767 GNUNET_free (op_name);
1768
1769 /* address pid */
1770 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1771 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1772 sec_name, op_name,
1773 &o->address_id))
1774 {
1775 fprintf (stderr,
1776 "Missing address-id in operation %u `%s' in episode `%s'\n",
1777 op_counter, "STOP_SET_PREFERENCE", op_name);
1778 GNUNET_free (op_name);
1779 return GNUNET_SYSERR;
1780 }
1781 GNUNET_free (op_name);
1782
1783 /* Get preference */
1784 GNUNET_asprintf (&op_name, "op-%u-pref", op_counter);
1785 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1786 sec_name, op_name,
1787 &pref))
1788 {
1789 fprintf (stderr,
1790 "Missing preference in operation %u `%s' in episode `%s'\n",
1791 op_counter, "STOP_SET_PREFERENCE", op_name);
1792 GNUNET_free (op_name);
1793 return GNUNET_SYSERR;
1794 }
1795
1796 if (0 == (o->pref_type = parse_preference_string (pref)))
1797 {
1798 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1799 op_counter, op_name, e->id);
1800 GNUNET_free (op_name);
1801 GNUNET_free (pref);
1802 return GNUNET_SYSERR;
1803 }
1804 GNUNET_free (pref);
1805 GNUNET_free (op_name);
1806
1807 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1808 "Found operation %s: [%llu:%llu]: %s\n",
1809 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
1810 GNUNET_ATS_print_preference_type (o->pref_type));
1811 return GNUNET_OK;
1812}
1813
1814
1815static enum GNUNET_ATS_Property
1816parse_property_string (const char *str)
1817{
1818 enum GNUNET_ATS_Property c;
1819
1820 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
1821 if (0 == strcmp (str,
1822 GNUNET_ATS_print_property_type (c)))
1823 return c;
1824 return 0;
1825}
1826
1827
1828static int
1829load_op_start_set_property (struct GNUNET_ATS_TEST_Operation *o,
1830 struct Episode *e,
1831 int op_counter,
1832 char *sec_name,
1833 const struct GNUNET_CONFIGURATION_Handle *cfg)
1834{
1835 char *op_name;
1836 char *type;
1837 char *prop;
1838
1839 /* peer pid */
1840 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
1841 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1842 sec_name, op_name,
1843 &o->peer_id))
1844 {
1845 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
1846 op_counter, "START_SET_PROPERTY", op_name);
1847 GNUNET_free (op_name);
1848 return GNUNET_SYSERR;
1849 }
1850 GNUNET_free (op_name);
1851
1852 /* address pid */
1853 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
1854 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1855 sec_name, op_name,
1856 &o->address_id))
1857 {
1858 fprintf (stderr,
1859 "Missing address-id in operation %u `%s' in episode `%s'\n",
1860 op_counter, "START_SET_PROPERTY", op_name);
1861 GNUNET_free (op_name);
1862 return GNUNET_SYSERR;
1863 }
1864 GNUNET_free (op_name);
1865
1866 /* generator */
1867 GNUNET_asprintf (&op_name, "op-%u-gen-type", op_counter);
1868 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1869 sec_name,
1870 op_name, &type)))
1871 {
1872 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
1873 op_counter, "START_SET_PROPERTY", op_name);
1874 GNUNET_free (op_name);
1875 return GNUNET_SYSERR;
1876 }
1877
1878 /* Load arguments for set_rate, start_send, set_preference */
1879 if (0 == strcmp (type, "constant"))
1880 {
1881 o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
1882 }
1883 else if (0 == strcmp (type, "linear"))
1884 {
1885 o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
1886 }
1887 else if (0 == strcmp (type, "sinus"))
1888 {
1889 o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
1890 }
1891 else if (0 == strcmp (type, "random"))
1892 {
1893 o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
1894 }
1895 else
1896 {
1897 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
1898 op_counter, op_name, e->id);
1899 GNUNET_free (type);
1900 GNUNET_free (op_name);
1901 return GNUNET_SYSERR;
1902 }
1903 GNUNET_free (type);
1904 GNUNET_free (op_name);
1905
1906
1907 /* Get base rate */
1908 GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter);
1909 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1910 sec_name, op_name,
1911 &o->base_rate))
1912 {
1913 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1914 op_counter, op_name, e->id);
1915 GNUNET_free (op_name);
1916 return GNUNET_SYSERR;
1917 }
1918 GNUNET_free (op_name);
1919
1920
1921 /* Get max rate */
1922 GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter);
1923 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1924 sec_name, op_name,
1925 &o->max_rate))
1926 {
1927 if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
1928 (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
1929 (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
1930 {
1931 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1932 op_counter, op_name, e->id);
1933 GNUNET_free (op_name);
1934 return GNUNET_SYSERR;
1935 }
1936 }
1937 GNUNET_free (op_name);
1938
1939 /* Get period */
1940 GNUNET_asprintf (&op_name, "op-%u-period", op_counter);
1941 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1942 sec_name, op_name,
1943 &o->period))
1944 {
1945 o->period = e->duration;
1946 }
1947 GNUNET_free (op_name);
1948
1949 /* Get frequency */
1950 GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter);
1951 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1952 sec_name, op_name,
1953 &o->frequency))
1954 {
1955 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1956 op_counter, op_name, e->id);
1957 GNUNET_free (op_name);
1958 return GNUNET_SYSERR;
1959 }
1960 GNUNET_free (op_name);
1961
1962 /* Get preference */
1963 GNUNET_asprintf (&op_name, "op-%u-property", op_counter);
1964 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1965 sec_name, op_name,
1966 &prop))
1967 {
1968 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
1969 op_counter, op_name, e->id);
1970 GNUNET_free (op_name);
1971 GNUNET_free (prop);
1972 return GNUNET_SYSERR;
1973 }
1974
1975 if (0 == (o->prop_type = parse_property_string (prop)))
1976 {
1977 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
1978 op_counter, op_name, e->id);
1979 GNUNET_free (op_name);
1980 GNUNET_free (prop);
1981 return GNUNET_SYSERR;
1982 }
1983
1984 GNUNET_free (prop);
1985 GNUNET_free (op_name);
1986
1987 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1988 "Found operation %s: [%llu:%llu] %s = %llu\n",
1989 "START_SET_PROPERTY", o->peer_id, o->address_id,
1990 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
1991
1992 return GNUNET_OK;
1993}
1994
1995
1996static int
1997load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
1998 struct Episode *e,
1999 int op_counter,
2000 char *sec_name,
2001 const struct GNUNET_CONFIGURATION_Handle *cfg)
2002{
2003 char *op_name;
2004 char *pref;
2005
2006 /* peer pid */
2007 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
2008 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2009 sec_name, op_name,
2010 &o->peer_id))
2011 {
2012 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
2013 op_counter, "STOP_SET_PROPERTY", op_name);
2014 GNUNET_free (op_name);
2015 return GNUNET_SYSERR;
2016 }
2017 GNUNET_free (op_name);
2018
2019 /* address pid */
2020 GNUNET_asprintf (&op_name, "op-%u-address-id", op_counter);
2021 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2022 sec_name, op_name,
2023 &o->address_id))
2024 {
2025 fprintf (stderr,
2026 "Missing address-id in operation %u `%s' in episode `%s'\n",
2027 op_counter, "STOP_SET_PROPERTY", op_name);
2028 GNUNET_free (op_name);
2029 return GNUNET_SYSERR;
2030 }
2031 GNUNET_free (op_name);
2032
2033 /* Get property */
2034 GNUNET_asprintf (&op_name, "op-%u-property", op_counter);
2035 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2036 sec_name, op_name,
2037 &pref))
2038 {
2039 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
2040 op_counter, "STOP_SET_PROPERTY", op_name);
2041 GNUNET_free (op_name);
2042 GNUNET_free (pref);
2043 return GNUNET_SYSERR;
2044 }
2045
2046 if (0 == (o->prop_type = parse_property_string (pref)))
2047 {
2048 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
2049 op_counter, op_name, e->id);
2050 GNUNET_free (op_name);
2051 GNUNET_free (pref);
2052 return GNUNET_SYSERR;
2053 }
2054
2055 GNUNET_free (pref);
2056 GNUNET_free (op_name);
2057
2058 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2059 "Found operation %s: [%llu:%llu] %s\n",
2060 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
2061 GNUNET_ATS_print_property_type (o->prop_type));
2062
2063 return GNUNET_OK;
2064}
2065
2066
2067static int
2068load_op_start_request (struct GNUNET_ATS_TEST_Operation *o,
2069 struct Episode *e,
2070 int op_counter,
2071 char *sec_name,
2072 const struct GNUNET_CONFIGURATION_Handle *cfg)
2073{
2074 char *op_name;
2075
2076 /* peer pid */
2077 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
2078 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2079 sec_name, op_name,
2080 &o->peer_id))
2081 {
2082 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
2083 op_counter, "START_REQUEST", op_name);
2084 GNUNET_free (op_name);
2085 return GNUNET_SYSERR;
2086 }
2087 GNUNET_free (op_name);
2088 return GNUNET_OK;
2089}
2090
2091
2092static int
2093load_op_stop_request (struct GNUNET_ATS_TEST_Operation *o,
2094 struct Episode *e,
2095 int op_counter,
2096 char *sec_name,
2097 const struct GNUNET_CONFIGURATION_Handle *cfg)
2098{
2099 char *op_name;
2100
2101 /* peer pid */
2102 GNUNET_asprintf (&op_name, "op-%u-peer-id", op_counter);
2103 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
2104 sec_name, op_name,
2105 &o->peer_id))
2106 {
2107 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
2108 op_counter, "STOP_REQUEST", op_name);
2109 GNUNET_free (op_name);
2110 return GNUNET_SYSERR;
2111 }
2112 GNUNET_free (op_name);
2113 return GNUNET_OK;
2114}
2115
2116
2117static int
2118load_episode (struct Experiment *e, struct Episode *cur,
2119 struct GNUNET_CONFIGURATION_Handle *cfg)
2120{
2121 struct GNUNET_ATS_TEST_Operation *o;
2122 char *sec_name;
2123 char *op_name;
2124 char *op;
2125 int op_counter = 0;
2126 int res;
2127
2128 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Parsing episode %u\n", cur->id);
2129 GNUNET_asprintf (&sec_name, "episode-%u", cur->id);
2130
2131 while (1)
2132 {
2133 /* Load operation */
2134 GNUNET_asprintf (&op_name, "op-%u-operation", op_counter);
2135 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2136 sec_name,
2137 op_name, &op))
2138 {
2139 GNUNET_free (op_name);
2140 break;
2141 }
2142 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
2143 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "==== Parsing operation %u: `%s'\n",
2144 cur->id, op_name);
2145
2146 /* operations = set_rate, start_send, stop_send, set_preference */
2147 if (0 == strcmp (op, "address_add"))
2148 {
2149 o->type = SOLVER_OP_ADD_ADDRESS;
2150 res = load_op_add_address (o, cur,
2151 op_counter, sec_name, cfg);
2152 }
2153 else if (0 == strcmp (op, "address_del"))
2154 {
2155 o->type = SOLVER_OP_DEL_ADDRESS;
2156 res = load_op_del_address (o, cur,
2157 op_counter, sec_name, cfg);
2158 }
2159 else if (0 == strcmp (op, "start_set_property"))
2160 {
2161 o->type = SOLVER_OP_START_SET_PROPERTY;
2162 res = load_op_start_set_property (o, cur,
2163 op_counter, sec_name, cfg);
2164 }
2165 else if (0 == strcmp (op, "stop_set_property"))
2166 {
2167 o->type = SOLVER_OP_STOP_SET_PROPERTY;
2168 res = load_op_stop_set_property (o, cur,
2169 op_counter, sec_name, cfg);
2170 }
2171 else if (0 == strcmp (op, "start_set_preference"))
2172 {
2173 o->type = SOLVER_OP_START_SET_PREFERENCE;
2174 res = load_op_start_set_preference (o, cur,
2175 op_counter, sec_name, cfg);
2176 }
2177 else if (0 == strcmp (op, "stop_set_preference"))
2178 {
2179 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
2180 res = load_op_stop_set_preference (o, cur,
2181 op_counter, sec_name, cfg);
2182 }
2183 else if (0 == strcmp (op, "start_request"))
2184 {
2185 o->type = SOLVER_OP_START_REQUEST;
2186 res = load_op_start_request (o, cur,
2187 op_counter, sec_name, cfg);
2188 }
2189 else if (0 == strcmp (op, "stop_request"))
2190 {
2191 o->type = SOLVER_OP_STOP_REQUEST;
2192 res = load_op_stop_request (o, cur,
2193 op_counter, sec_name, cfg);
2194 }
2195 else
2196 {
2197 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
2198 op_counter, op, cur->id);
2199 res = GNUNET_SYSERR;
2200 }
2201
2202 GNUNET_free (op);
2203 GNUNET_free (op_name);
2204
2205 if (GNUNET_SYSERR == res)
2206 {
2207 GNUNET_free (o);
2208 GNUNET_free (sec_name);
2209 return GNUNET_SYSERR;
2210 }
2211
2212 GNUNET_CONTAINER_DLL_insert_tail (cur->head, cur->tail, o);
2213 op_counter++;
2214 }
2215 GNUNET_free (sec_name);
2216 return GNUNET_OK;
2217}
2218
2219
2220static int
2221load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
2222{
2223 int e_counter = 0;
2224 char *sec_name;
2225 struct GNUNET_TIME_Relative e_duration;
2226 struct Episode *cur;
2227 struct Episode *last;
2228
2229 e_counter = 0;
2230 last = NULL;
2231 while (1)
2232 {
2233 GNUNET_asprintf (&sec_name, "episode-%u", e_counter);
2234 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
2235 sec_name,
2236 "duration",
2237 &e_duration))
2238 {
2239 GNUNET_free (sec_name);
2240 break;
2241 }
2242
2243 cur = GNUNET_new (struct Episode);
2244 cur->duration = e_duration;
2245 cur->id = e_counter;
2246
2247 if (GNUNET_OK != load_episode (e, cur, cfg))
2248 {
2249 GNUNET_free (sec_name);
2250 GNUNET_free (cur);
2251 return GNUNET_SYSERR;
2252 }
2253
2254 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Found episode %u with duration %s \n",
2255 e_counter,
2256 GNUNET_STRINGS_relative_time_to_string (cur->duration,
2257 GNUNET_YES));
2258
2259 /* Update experiment */
2260 e->num_episodes++;
2261 e->total_duration = GNUNET_TIME_relative_add (e->total_duration,
2262 cur->duration);
2263 /* Put in linked list */
2264 if (NULL == last)
2265 e->start = cur;
2266 else
2267 last->next = cur;
2268
2269 GNUNET_free (sec_name);
2270 e_counter++;
2271 last = cur;
2272 }
2273 return e_counter;
2274}
2275
2276
2277static void
2278timeout_experiment (void *cls)
2279{
2280 struct Experiment *e = cls;
2281
2282 e->experiment_timeout_task = NULL;
2283 fprintf (stderr, "Experiment timeout!\n");
2284
2285 if (NULL != e->episode_timeout_task)
2286 {
2287 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2288 e->episode_timeout_task = NULL;
2289 }
2290
2291 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
2292 GNUNET_SYSERR);
2293}
2294
2295
2296struct ATS_Address *
2297create_ats_address (const struct GNUNET_PeerIdentity *peer,
2298 const char *plugin_name,
2299 const void *plugin_addr,
2300 size_t plugin_addr_len,
2301 uint32_t session_id,
2302 uint32_t network)
2303{
2304 struct ATS_Address *aa = NULL;
2305
2306 aa = GNUNET_malloc (sizeof(struct ATS_Address) + plugin_addr_len + strlen (
2307 plugin_name) + 1);
2308 aa->atsi = GNUNET_new (struct GNUNET_ATS_Information);
2309 aa->atsi[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
2310 aa->atsi[0].value = htonl (network);
2311 aa->atsi_count = 1;
2312
2313 aa->peer = *peer;
2314 aa->addr_len = plugin_addr_len;
2315 aa->addr = &aa[1];
2316 aa->plugin = (char *) &aa[1] + plugin_addr_len;
2317 GNUNET_memcpy (&aa[1], plugin_addr, plugin_addr_len);
2318 GNUNET_memcpy (aa->plugin, plugin_name, strlen (plugin_name) + 1);
2319 aa->session_id = session_id;
2320
2321 return aa;
2322}
2323
2324
2325static void
2326enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
2327{
2328 struct TestPeer *p;
2329 struct TestAddress *a;
2330 int c;
2331
2332 if (NULL == (p = find_peer_by_id (op->peer_id)))
2333 {
2334 p = GNUNET_new (struct TestPeer);
2335 p->id = op->peer_id;
2336 p->assigned_bw_in = 0;
2337 p->assigned_bw_out = 0;
2338 memset (&p->peer_id, op->peer_id, sizeof(p->peer_id));
2339 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
2340 {
2341 p->pref_abs[c] = DEFAULT_ABS_PREFERENCE;
2342 p->pref_norm[c] = DEFAULT_REL_PREFERENCE;
2343 }
2344
2345 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, p);
2346 }
2347
2348 if (NULL != (find_address_by_id (p, op->address_id)))
2349 {
2350 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Duplicate address %u for peer %u\n",
2351 op->address_id, op->peer_id);
2352 return;
2353 }
2354
2355 a = GNUNET_new (struct TestAddress);
2356 a->aid = op->address_id;
2357 a->network = op->address_network;
2358 a->ats_addr = create_ats_address (&p->peer_id, op->plugin, op->address,
2359 strlen (op->address) + 1,
2360 op->address_session, op->address_network);
2361 memset (&p->peer_id, op->peer_id, sizeof(p->peer_id));
2362 GNUNET_CONTAINER_DLL_insert_tail (p->addr_head, p->addr_tail, a);
2363
2364 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
2365 a->prop_norm[c] = DEFAULT_REL_QUALITY;
2366
2367 GNUNET_CONTAINER_multipeermap_put (sh->addresses, &p->peer_id, a->ats_addr,
2368 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2369
2370 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2371 "Adding address %u for peer %u in network `%s'\n",
2372 op->address_id, op->peer_id, GNUNET_NT_to_string (a->network));
2373
2374 sh->sf->s_add (sh->sf->cls, a->ats_addr, op->address_network);
2375}
2376
2377
2378static void
2379enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
2380{
2381 struct TestPeer *p;
2382 struct TestAddress *a;
2383 struct PropertyGenerator *pg;
2384
2385 if (NULL == (p = find_peer_by_id (op->peer_id)))
2386 {
2387 GNUNET_break (0);
2388 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2389 "Deleting address for unknown peer %u\n", op->peer_id);
2390 return;
2391 }
2392
2393 if (NULL == (a = find_address_by_id (p, op->address_id)))
2394 {
2395 GNUNET_break (0);
2396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2397 "Deleting address for unknown peer %u\n", op->peer_id);
2398 return;
2399 }
2400
2401 while (NULL != (pg = find_prop_gen (p->id, a->aid, 0)))
2402 {
2403 GNUNET_ATS_solver_generate_property_stop (pg);
2404 }
2405
2406 GNUNET_assert (GNUNET_YES ==
2407 GNUNET_CONTAINER_multipeermap_remove (sh->addresses,
2408 &p->peer_id,
2409 a->ats_addr));
2410 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2411 "Removing address %u for peer %u\n",
2412 op->address_id,
2413 op->peer_id);
2414
2415 sh->sf->s_del (sh->sf->cls, a->ats_addr);
2416
2417 if (NULL != l)
2418 {
2419 GNUNET_ATS_solver_logging_now (l);
2420 }
2421 GNUNET_CONTAINER_DLL_remove (p->addr_head, p->addr_tail, a);
2422
2423 GNUNET_free (a->ats_addr->atsi);
2424 GNUNET_free (a->ats_addr);
2425 GNUNET_free (a);
2426}
2427
2428
2429static void
2430enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
2431{
2432 struct PropertyGenerator *pg;
2433 struct TestPeer *p;
2434 struct TestAddress *a;
2435
2436 if (NULL != (pg = find_prop_gen (op->peer_id, op->address_id, op->prop_type)))
2437 {
2438 GNUNET_ATS_solver_generate_property_stop (pg);
2439 GNUNET_free (pg);
2440 }
2441
2442 if (NULL == (p = find_peer_by_id (op->peer_id)))
2443 {
2444 GNUNET_break (0);
2445 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2446 "Starting property generation for unknown peer %u\n",
2447 op->peer_id);
2448 return;
2449 }
2450
2451 if (NULL == (a = find_address_by_id (p, op->address_id)))
2452 {
2453 GNUNET_break (0);
2454 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2455 "Setting property for unknown address %u\n", op->peer_id);
2456 return;
2457 }
2458
2459 GNUNET_ATS_solver_generate_property_start (op->peer_id,
2460 op->address_id,
2461 p, a,
2462 op->gen_type,
2463 op->base_rate,
2464 op->max_rate,
2465 op->period,
2466 op->frequency,
2467 op->prop_type);
2468}
2469
2470
2471static void
2472enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
2473{
2474 struct PropertyGenerator *pg = find_prop_gen (op->peer_id, op->address_id,
2475 op->prop_type);
2476
2477 if (NULL != pg)
2478 {
2479 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2480 "Stopping preference generation for peer %u address %u\n",
2481 op->peer_id,
2482 op->address_id);
2483 GNUNET_ATS_solver_generate_property_stop (pg);
2484 }
2485 else
2486 {
2487 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2488 "Cannot find preference generator for peer %u address %u\n",
2489 op->peer_id, op->address_id);
2490 GNUNET_break (0);
2491 }
2492}
2493
2494
2495static void
2496enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
2497{
2498 struct PreferenceGenerator *pg;
2499
2500 if (NULL != (pg = find_pref_gen (op->peer_id, op->pref_type)))
2501 {
2502 GNUNET_ATS_solver_generate_preferences_stop (pg);
2503 GNUNET_free (pg);
2504 }
2505
2506 if (NULL == (find_peer_by_id (op->peer_id)))
2507 {
2508 GNUNET_break (0);
2509 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2510 "Starting preference generation for unknown peer %u\n",
2511 op->peer_id);
2512 return;
2513 }
2514
2515 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
2516 op->address_id,
2517 op->client_id,
2518 op->gen_type,
2519 op->base_rate,
2520 op->max_rate,
2521 op->period,
2522 op->frequency,
2523 op->pref_type,
2524 op->frequency);
2525}
2526
2527
2528static void
2529enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
2530{
2531 struct PreferenceGenerator *pg = find_pref_gen (op->peer_id,
2532 op->pref_type);
2533
2534 if (NULL != pg)
2535 {
2536 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2537 "Stopping property generation for peer %u address %u\n",
2538 op->peer_id,
2539 op->address_id);
2540 GNUNET_ATS_solver_generate_preferences_stop (pg);
2541 }
2542 else
2543 {
2544 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2545 "Cannot find preference generator for peer %u address %u\n",
2546 op->peer_id, op->address_id);
2547 GNUNET_break (0);
2548 }
2549}
2550
2551
2552static void
2553enforce_start_request (struct GNUNET_ATS_TEST_Operation *op)
2554{
2555 struct TestPeer *p;
2556
2557 if (NULL == (p = find_peer_by_id (op->peer_id)))
2558 {
2559 GNUNET_break (0);
2560 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2561 "Requesting address for unknown peer %u\n", op->peer_id);
2562 return;
2563 }
2564
2565 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting address for peer %u\n",
2566 op->peer_id);
2567 p->is_requested = GNUNET_YES;
2568
2569 sh->sf->s_get (sh->sf->cls, &p->peer_id);
2570}
2571
2572
2573static void
2574enforce_stop_request (struct GNUNET_ATS_TEST_Operation *op)
2575{
2576 struct TestPeer *p;
2577
2578 if (NULL == (p = find_peer_by_id (op->peer_id)))
2579 {
2580 GNUNET_break (0);
2581 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2582 "Requesting address for unknown peer %u\n", op->peer_id);
2583 return;
2584 }
2585
2586 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2587 "Stop requesting address for peer %u\n",
2588 op->peer_id);
2589 p->is_requested = GNUNET_NO;
2590 p->assigned_bw_in = 0;
2591 p->assigned_bw_out = 0;
2592 sh->sf->s_get_stop (sh->sf->cls, &p->peer_id);
2593
2594 if (NULL != l)
2595 {
2596 GNUNET_ATS_solver_logging_now (l);
2597 }
2598}
2599
2600
2601static void
2602enforce_episode (struct Episode *ep)
2603{
2604 struct GNUNET_ATS_TEST_Operation *cur;
2605
2606 for (cur = ep->head; NULL != cur; cur = cur->next)
2607 {
2608 switch (cur->type)
2609 {
2610 case SOLVER_OP_ADD_ADDRESS:
2611 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2612 print_op (cur->type), cur->peer_id, cur->address_id);
2613 enforce_add_address (cur);
2614 break;
2615
2616 case SOLVER_OP_DEL_ADDRESS:
2617 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
2618 print_op (cur->type), cur->peer_id, cur->address_id);
2619 enforce_del_address (cur);
2620 break;
2621
2622 case SOLVER_OP_START_SET_PROPERTY:
2623 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2624 print_op (cur->type), cur->peer_id, cur->address_id,
2625 cur->base_rate);
2626 enforce_start_property (cur);
2627 break;
2628
2629 case SOLVER_OP_STOP_SET_PROPERTY:
2630 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2631 print_op (cur->type), cur->peer_id, cur->address_id,
2632 cur->base_rate);
2633 enforce_stop_property (cur);
2634 break;
2635
2636 case SOLVER_OP_START_SET_PREFERENCE:
2637 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2638 print_op (cur->type), cur->peer_id, cur->address_id,
2639 cur->base_rate);
2640 enforce_start_preference (cur);
2641 break;
2642
2643 case SOLVER_OP_STOP_SET_PREFERENCE:
2644 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
2645 print_op (cur->type), cur->peer_id, cur->address_id,
2646 cur->base_rate);
2647 enforce_stop_preference (cur);
2648 break;
2649
2650 case SOLVER_OP_START_REQUEST:
2651 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2652 print_op (cur->type), cur->peer_id);
2653 enforce_start_request (cur);
2654 break;
2655
2656 case SOLVER_OP_STOP_REQUEST:
2657 fprintf (stderr, "Enforcing operation: %s [%llu]\n",
2658 print_op (cur->type), cur->peer_id);
2659 enforce_stop_request (cur);
2660 break;
2661
2662 default:
2663 break;
2664 }
2665 }
2666}
2667
2668
2669static void
2670timeout_episode (void *cls)
2671{
2672 struct Experiment *e = cls;
2673
2674 e->episode_timeout_task = NULL;
2675 if (NULL != e->ep_done_cb)
2676 e->ep_done_cb (e->cur);
2677
2678 /* Scheduling next */
2679 e->cur = e->cur->next;
2680 if (NULL == e->cur)
2681 {
2682 /* done */
2683 fprintf (stderr, "Last episode done!\n");
2684 if (NULL != e->experiment_timeout_task)
2685 {
2686 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2687 e->experiment_timeout_task = NULL;
2688 }
2689 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time),
2690 GNUNET_OK);
2691 return;
2692 }
2693
2694 fprintf (stderr, "Running episode %u with timeout %s\n",
2695 e->cur->id,
2696 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
2697 GNUNET_YES));
2698 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2699 &timeout_episode, e);
2700 enforce_episode (e->cur);
2701}
2702
2703
2704void
2705GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
2706 GNUNET_ATS_TESTING_EpisodeDoneCallback
2707 ep_done_cb,
2708 GNUNET_ATS_TESTING_ExperimentDoneCallback
2709 e_done_cb)
2710{
2711 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
2712 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
2713 GNUNET_YES));
2714 e->e_done_cb = e_done_cb;
2715 e->ep_done_cb = ep_done_cb;
2716 e->start_time = GNUNET_TIME_absolute_get ();
2717
2718 /* Start total time out */
2719 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
2720 &timeout_experiment,
2721 e);
2722
2723 /* Start */
2724 if (NULL == e->start)
2725 {
2726 GNUNET_break (0);
2727 return;
2728 }
2729
2730 e->cur = e->start;
2731 fprintf (stderr, "Running episode %u with timeout %s\n",
2732 e->cur->id,
2733 GNUNET_STRINGS_relative_time_to_string (e->cur->duration,
2734 GNUNET_YES));
2735 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
2736 &timeout_episode, e);
2737 enforce_episode (e->cur);
2738}
2739
2740
2741void
2742GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
2743{
2744 if (NULL != e->experiment_timeout_task)
2745 {
2746 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
2747 e->experiment_timeout_task = NULL;
2748 }
2749 if (NULL != e->episode_timeout_task)
2750 {
2751 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
2752 e->episode_timeout_task = NULL;
2753 }
2754 if (NULL != e->cfg)
2755 {
2756 GNUNET_CONFIGURATION_destroy (e->cfg);
2757 e->cfg = NULL;
2758 }
2759 free_experiment (e);
2760}
2761
2762
2763struct Experiment *
2764GNUNET_ATS_solvers_experimentation_load (char *filename)
2765{
2766 struct Experiment *e;
2767 struct GNUNET_CONFIGURATION_Handle *cfg;
2768
2769 e = NULL;
2770
2771 cfg = GNUNET_CONFIGURATION_create ();
2772 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
2773 {
2774 fprintf (stderr, "Failed to load `%s'\n", filename);
2775 GNUNET_CONFIGURATION_destroy (cfg);
2776 return NULL;
2777 }
2778
2779 e = create_experiment ();
2780
2781 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment",
2782 "name", &e->name))
2783 {
2784 fprintf (stderr, "Invalid %s \n", "name");
2785 free_experiment (e);
2786 return NULL;
2787 }
2788 else
2789 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name);
2790
2791 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment",
2792 "log_prefix",
2793 &e->log_prefix))
2794 {
2795 fprintf (stderr, "Invalid %s \n", "log_prefix");
2796 free_experiment (e);
2797 return NULL;
2798 }
2799 else
2800 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging prefix: `%s'\n",
2801 e->log_prefix);
2802
2803 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg,
2804 "experiment",
2805 "log_output_dir",
2806 &e->
2807 log_output_dir))
2808 {
2809 e->log_output_dir = NULL;
2810 }
2811 else
2812 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2813 "Experiment logging output directory: `%s'\n",
2814 e->log_output_dir);
2815
2816
2817 if (GNUNET_SYSERR == (e->log_append_time_stamp =
2818 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2819 "experiment",
2820 "log_append_time_stamp")))
2821 e->log_append_time_stamp = GNUNET_YES;
2822 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2823 "Experiment logging append timestamp: `%s'\n",
2824 (GNUNET_YES == e->log_append_time_stamp) ? "yes" : "no");
2825
2826
2827 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg,
2828 "experiment",
2829 "cfg_file",
2830 &e->cfg_file))
2831 {
2832 fprintf (stderr, "Invalid %s \n", "cfg_file");
2833 free_experiment (e);
2834 return NULL;
2835 }
2836 else
2837 {
2838 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment configuration: `%s'\n",
2839 e->cfg_file);
2840 e->cfg = GNUNET_CONFIGURATION_create ();
2841 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2842 {
2843 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2844 free_experiment (e);
2845 return NULL;
2846 }
2847 }
2848
2849 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
2850 "log_freq",
2851 &e->log_freq))
2852 {
2853 fprintf (stderr, "Invalid %s \n", "log_freq");
2854 free_experiment (e);
2855 return NULL;
2856 }
2857 else
2858 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment logging frequency: `%s'\n",
2859 GNUNET_STRINGS_relative_time_to_string (e->log_freq,
2860 GNUNET_YES));
2861
2862 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment",
2863 "max_duration",
2864 &e->max_duration))
2865 {
2866 fprintf (stderr, "Invalid %s", "max_duration");
2867 free_experiment (e);
2868 return NULL;
2869 }
2870 else
2871 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n",
2872 GNUNET_STRINGS_relative_time_to_string (e->max_duration,
2873 GNUNET_YES));
2874
2875 if (GNUNET_SYSERR == load_episodes (e, cfg))
2876 {
2877 GNUNET_ATS_solvers_experimentation_stop (e);
2878 GNUNET_CONFIGURATION_destroy (cfg);
2879 e = NULL;
2880 fprintf (stderr, "Failed to load experiment\n");
2881 return NULL;
2882 }
2883 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2884 "Loaded %u episodes with total duration %s\n",
2885 e->num_episodes,
2886 GNUNET_STRINGS_relative_time_to_string (e->total_duration,
2887 GNUNET_YES));
2888
2889 GNUNET_CONFIGURATION_destroy (cfg);
2890 return e;
2891}
2892
2893
2894/**
2895 * Solver
2896 */
2897
2898static int
2899free_all_it (void *cls,
2900 const struct GNUNET_PeerIdentity *key,
2901 void *value)
2902{
2903 struct ATS_Address *address = value;
2904
2905 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (
2906 sh->env.addresses,
2907 key, value));
2908 GNUNET_free (address);
2909
2910 return GNUNET_OK;
2911}
2912
2913
2914void
2915GNUNET_ATS_solvers_solver_stop (struct SolverHandle *sh)
2916{
2917 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
2918 GNUNET_NO);
2919 GNUNET_PLUGIN_unload (sh->plugin, sh->sf);
2920 sh->sf = NULL;
2921 GAS_normalization_stop ();
2922
2923 GNUNET_CONTAINER_multipeermap_iterate (sh->addresses,
2924 &free_all_it,
2925 NULL);
2926 GNUNET_CONTAINER_multipeermap_destroy (sh->addresses);
2927 GNUNET_free (sh->plugin);
2928 GNUNET_free (sh);
2929}
2930
2931
2932/**
2933 * Load quotas for networks from configuration
2934 *
2935 * @param cfg configuration handle
2936 * @param out_dest where to write outbound quotas
2937 * @param in_dest where to write inbound quotas
2938 * @param dest_length length of inbound and outbound arrays
2939 * @return number of networks loaded
2940 */
2941unsigned int
2942GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
2943 unsigned long long *out_dest,
2944 unsigned long long *in_dest,
2945 int dest_length)
2946{
2947 char *entry_in = NULL;
2948 char *entry_out = NULL;
2949 char *quota_out_str;
2950 char *quota_in_str;
2951 int c;
2952 int res;
2953
2954 for (c = 0; (c < GNUNET_NT_COUNT) && (c < dest_length); c++)
2955 {
2956 in_dest[c] = 0;
2957 out_dest[c] = 0;
2958 GNUNET_asprintf (&entry_out,
2959 "%s_QUOTA_OUT",
2960 GNUNET_NT_to_string (c));
2961 GNUNET_asprintf (&entry_in,
2962 "%s_QUOTA_IN",
2963 GNUNET_NT_to_string (c));
2964
2965 /* quota out */
2966 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "ats",
2967 entry_out,
2968 &quota_out_str))
2969 {
2970 res = GNUNET_NO;
2971 if (0 == strcmp (quota_out_str, BIG_M_STRING))
2972 {
2973 out_dest[c] = GNUNET_ATS_MaxBandwidth;
2974 res = GNUNET_YES;
2975 }
2976 if ((GNUNET_NO == res) && (GNUNET_OK ==
2977 GNUNET_STRINGS_fancy_size_to_bytes (
2978 quota_out_str, &out_dest[c])))
2979 res = GNUNET_YES;
2980 if ((GNUNET_NO == res) && (GNUNET_OK ==
2981 GNUNET_CONFIGURATION_get_value_number (cfg,
2982 "ats",
2983 entry_out,
2984 &
2985 out_dest
2986 [c])))
2987 res = GNUNET_YES;
2988
2989 if (GNUNET_NO == res)
2990 {
2991 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2992 _ (
2993 "Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
2994 GNUNET_NT_to_string (c),
2995 quota_out_str,
2996 GNUNET_ATS_DefaultBandwidth);
2997 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
2998 }
2999 else
3000 {
3001 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3002 "Outbound quota configure for network `%s' is %llu\n",
3003 GNUNET_NT_to_string (c),
3004 out_dest[c]);
3005 }
3006 GNUNET_free (quota_out_str);
3007 }
3008 else
3009 {
3010 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3011 _ (
3012 "No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
3013 GNUNET_NT_to_string (c),
3014 GNUNET_ATS_DefaultBandwidth);
3015 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
3016 }
3017
3018 /* quota in */
3019 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "ats",
3020 entry_in,
3021 &quota_in_str))
3022 {
3023 res = GNUNET_NO;
3024 if (0 == strcmp (quota_in_str, BIG_M_STRING))
3025 {
3026 in_dest[c] = GNUNET_ATS_MaxBandwidth;
3027 res = GNUNET_YES;
3028 }
3029 if ((GNUNET_NO == res) && (GNUNET_OK ==
3030 GNUNET_STRINGS_fancy_size_to_bytes (
3031 quota_in_str, &in_dest[c])))
3032 res = GNUNET_YES;
3033 if ((GNUNET_NO == res) && (GNUNET_OK ==
3034 GNUNET_CONFIGURATION_get_value_number (cfg,
3035 "ats",
3036 entry_in,
3037 &in_dest
3038 [c])))
3039 res = GNUNET_YES;
3040
3041 if (GNUNET_NO == res)
3042 {
3043 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3044 _ (
3045 "Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
3046 GNUNET_NT_to_string (c),
3047 quota_in_str,
3048 GNUNET_ATS_DefaultBandwidth);
3049 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
3050 }
3051 else
3052 {
3053 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3054 "Inbound quota configured for network `%s' is %llu\n",
3055 GNUNET_NT_to_string (c),
3056 in_dest[c]);
3057 }
3058 GNUNET_free (quota_in_str);
3059 }
3060 else
3061 {
3062 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3063 _ (
3064 "No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
3065 GNUNET_NT_to_string (c),
3066 GNUNET_ATS_DefaultBandwidth);
3067 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
3068 }
3069 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3070 "Loaded quota for network `%s' (in/out): %llu %llu\n",
3071 GNUNET_NT_to_string (c),
3072 in_dest[c],
3073 out_dest[c]);
3074 GNUNET_free (entry_out);
3075 GNUNET_free (entry_in);
3076 }
3077 return GNUNET_NT_COUNT;
3078}
3079
3080
3081/**
3082 * Information callback for the solver
3083 *
3084 * @param cls the closure
3085 * @param op the solver operation
3086 * @param stat status of the solver operation
3087 * @param add additional solver information
3088 */
3089static void
3090solver_info_cb (void *cls,
3091 enum GAS_Solver_Operation op,
3092 enum GAS_Solver_Status stat,
3093 enum GAS_Solver_Additional_Information add)
3094{
3095 char *add_info;
3096
3097 switch (add)
3098 {
3099 case GAS_INFO_NONE:
3100 add_info = "GAS_INFO_NONE";
3101 break;
3102
3103 case GAS_INFO_FULL:
3104 add_info = "GAS_INFO_MLP_FULL";
3105 break;
3106
3107 case GAS_INFO_UPDATED:
3108 add_info = "GAS_INFO_MLP_UPDATED";
3109 break;
3110
3111 case GAS_INFO_PROP_ALL:
3112 add_info = "GAS_INFO_PROP_ALL";
3113 break;
3114
3115 case GAS_INFO_PROP_SINGLE:
3116 add_info = "GAS_INFO_PROP_SINGLE";
3117 break;
3118
3119 default:
3120 add_info = "INVALID";
3121 break;
3122 }
3123
3124 switch (op)
3125 {
3126 case GAS_OP_SOLVE_START:
3127 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3128 "Solver notifies `%s' with result `%s' `%s'\n",
3129 "GAS_OP_SOLVE_START",
3130 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
3131 return;
3132
3133 case GAS_OP_SOLVE_STOP:
3134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3135 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
3136 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
3137 return;
3138
3139 case GAS_OP_SOLVE_SETUP_START:
3140 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3141 "Solver notifies `%s' with result `%s'\n",
3142 "GAS_OP_SOLVE_SETUP_START",
3143 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3144 return;
3145
3146 case GAS_OP_SOLVE_SETUP_STOP:
3147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3148 "Solver notifies `%s' with result `%s'\n",
3149 "GAS_OP_SOLVE_SETUP_STOP",
3150 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3151 return;
3152
3153 case GAS_OP_SOLVE_MLP_LP_START:
3154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3155 "Solver notifies `%s' with result `%s'\n",
3156 "GAS_OP_SOLVE_LP_START",
3157 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3158 return;
3159
3160 case GAS_OP_SOLVE_MLP_LP_STOP:
3161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3162 "Solver notifies `%s' with result `%s'\n",
3163 "GAS_OP_SOLVE_LP_STOP",
3164 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3165 return;
3166
3167 case GAS_OP_SOLVE_MLP_MLP_START:
3168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3169 "Solver notifies `%s' with result `%s'\n",
3170 "GAS_OP_SOLVE_MLP_START",
3171 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3172 return;
3173
3174 case GAS_OP_SOLVE_MLP_MLP_STOP:
3175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3176 "Solver notifies `%s' with result `%s'\n",
3177 "GAS_OP_SOLVE_MLP_STOP",
3178 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3179 return;
3180
3181 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
3182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3183 "Solver notifies `%s' with result `%s'\n",
3184 "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
3185 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3186 return;
3187
3188 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
3189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3190 "Solver notifies `%s' with result `%s'\n",
3191 "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
3192 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
3193 return;
3194
3195 default:
3196 break;
3197 }
3198}
3199
3200
3201static void
3202solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
3203{
3204 struct GNUNET_TIME_Relative duration;
3205 struct TestPeer *p;
3206 static struct PreferenceGenerator *pg;
3207 uint32_t delta;
3208
3209 if ((0 == address->assigned_bw_out) && (0 == address->assigned_bw_in))
3210 {
3211 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3212 "Solver notified to disconnect peer `%s'\n",
3213 GNUNET_i2s (&address->peer));
3214 }
3215 p = find_peer_by_pid (&address->peer);
3216 if (NULL == p)
3217 return;
3218 p->assigned_bw_out = address->assigned_bw_out;
3219 p->assigned_bw_in = address->assigned_bw_in;
3220
3221 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
3222 {
3223 if (pg->peer == p->id)
3224 {
3225 duration = GNUNET_TIME_absolute_get_duration (
3226 pg->feedback_last_bw_update);
3227 delta = duration.rel_value_us * pg->last_assigned_bw_out;
3228 pg->feedback_bw_out_acc += delta;
3229
3230 delta = duration.rel_value_us * pg->last_assigned_bw_in;
3231 pg->feedback_bw_in_acc += delta;
3232
3233 pg->last_assigned_bw_in = address->assigned_bw_in;
3234 pg->last_assigned_bw_out = address->assigned_bw_out;
3235 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get ();
3236 }
3237 }
3238
3239 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3240 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
3241 GNUNET_i2s (&address->peer),
3242 address,
3243 address->assigned_bw_out,
3244 address->assigned_bw_in);
3245
3246 if (NULL != l)
3247 GNUNET_ATS_solver_logging_now (l);
3248
3249 return;
3250}
3251
3252
3253const double *
3254get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3255{
3256 struct TestPeer *p;
3257
3258 if (GNUNET_YES == opt_disable_normalization)
3259 {
3260 if (NULL == (p = find_peer_by_pid (id)))
3261 return NULL;
3262 return p->pref_abs;
3263 }
3264 else
3265 return GAS_preference_get_by_peer (NULL,
3266 id);
3267}
3268
3269
3270struct SolverHandle *
3271GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3272{
3273 struct SolverHandle *sh;
3274 char *solver_str;
3275
3276 switch (type)
3277 {
3278 case GNUNET_ATS_SOLVER_PROPORTIONAL:
3279 solver_str = "proportional";
3280 break;
3281
3282 case GNUNET_ATS_SOLVER_MLP:
3283 solver_str = "mlp";
3284 break;
3285
3286 case GNUNET_ATS_SOLVER_RIL:
3287 solver_str = "ril";
3288 break;
3289
3290 default:
3291 GNUNET_break (0);
3292 return NULL;
3293 break;
3294 }
3295
3296 sh = GNUNET_new (struct SolverHandle);
3297 GNUNET_asprintf (&sh->plugin,
3298 "libgnunet_plugin_ats_%s",
3299 solver_str);
3300 sh->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
3301
3302 /* setup environment */
3303 sh->env.cfg = e->cfg;
3304 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
3305 sh->env.addresses = sh->addresses;
3306 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
3307 sh->env.get_preferences = &get_preferences_cb;
3308 sh->env.network_count = GNUNET_NT_COUNT;
3309 sh->env.info_cb = &solver_info_cb;
3310 sh->env.network_count = GNUNET_NT_COUNT;
3311
3312 /* start normalization */
3313 GAS_normalization_start ();
3314
3315 /* load quotas */
3316 if (GNUNET_NT_COUNT != GNUNET_ATS_solvers_load_quotas (e->cfg,
3317 sh->env.out_quota,
3318 sh->env.in_quota,
3319 GNUNET_NT_COUNT))
3320 {
3321 GNUNET_break (0);
3322 GNUNET_free (sh->plugin);
3323 GNUNET_free (sh);
3324 end_now ();
3325 return NULL;
3326 }
3327
3328 sh->sf = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
3329 if (NULL == sh->sf)
3330 {
3331 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
3332 GNUNET_break (0);
3333 GNUNET_free (sh->plugin);
3334 GNUNET_free (sh);
3335 end_now ();
3336 return NULL;
3337 }
3338 return sh;
3339}
3340
3341
3342static void
3343done ()
3344{
3345 struct TestPeer *cur;
3346 struct TestPeer *next;
3347
3348 struct TestAddress *cur_a;
3349 struct TestAddress *next_a;
3350
3351 /* Stop logging */
3352 GNUNET_ATS_solver_logging_stop (l);
3353
3354 /* Stop all preference generation */
3355 GNUNET_ATS_solver_generate_preferences_stop_all ();
3356
3357 /* Stop all property generation */
3358 GNUNET_ATS_solver_generate_property_stop_all ();
3359
3360 if (opt_print)
3361 {
3362 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Printing log information \n");
3363 GNUNET_ATS_solver_logging_eval (l);
3364 }
3365 if (opt_save)
3366 {
3367 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "== Saving log information \n");
3368 GNUNET_ATS_solver_logging_write_to_disk (l, e->log_append_time_stamp,
3369 e->log_output_dir);
3370 }
3371
3372 if (NULL != l)
3373 {
3374 GNUNET_ATS_solver_logging_free (l);
3375 l = NULL;
3376 }
3377
3378 /* Clean up experiment */
3379 if (NULL != e)
3380 {
3381 GNUNET_ATS_solvers_experimentation_stop (e);
3382 e = NULL;
3383 }
3384
3385 next = peer_head;
3386 while (NULL != (cur = next))
3387 {
3388 next = cur->next;
3389 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, cur);
3390 next_a = cur->addr_head;
3391 while (NULL != (cur_a = next_a))
3392 {
3393 next_a = cur_a->next;
3394 GNUNET_CONTAINER_DLL_remove (cur->addr_head, cur->addr_tail, cur_a);
3395 GNUNET_free (cur_a);
3396 }
3397 GNUNET_free (cur);
3398 }
3399 if (NULL != sh)
3400 {
3401 GNUNET_ATS_solvers_solver_stop (sh);
3402 sh = NULL;
3403 }
3404
3405 /* Shutdown */
3406 end_now ();
3407}
3408
3409
3410static void
3411experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,
3412 int success)
3413{
3414 if (GNUNET_OK == success)
3415 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
3416 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
3417 else
3418 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
3419
3420 GNUNET_SCHEDULER_add_now (&done, NULL);
3421}
3422
3423
3424static void
3425episode_done_cb (struct Episode *ep)
3426{
3427 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
3428}
3429
3430
3431/**
3432 * Do shutdown
3433 */
3434static void
3435end_now ()
3436{
3437 if (NULL != e)
3438 {
3439 GNUNET_ATS_solvers_experimentation_stop (e);
3440 e = NULL;
3441 }
3442 if (NULL != sh)
3443 {
3444 GNUNET_ATS_solvers_solver_stop (sh);
3445 sh = NULL;
3446 }
3447}
3448
3449
3450static void
3451run (void *cls, char *const *args, const char *cfgfile,
3452 const struct GNUNET_CONFIGURATION_Handle *cfg)
3453{
3454 enum GNUNET_ATS_Solvers solver;
3455 int c;
3456
3457 if (NULL == opt_exp_file)
3458 {
3459 fprintf (stderr, "No experiment given ...\n");
3460 res = 1;
3461 end_now ();
3462 return;
3463 }
3464
3465 if (NULL == opt_solver)
3466 {
3467 fprintf (stderr, "No solver given ...\n");
3468 res = 1;
3469 end_now ();
3470 return;
3471 }
3472
3473 if (0 == strcmp (opt_solver, "mlp"))
3474 {
3475 solver = GNUNET_ATS_SOLVER_MLP;
3476 }
3477 else if (0 == strcmp (opt_solver, "proportional"))
3478 {
3479 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
3480 }
3481 else if (0 == strcmp (opt_solver, "ril"))
3482 {
3483 solver = GNUNET_ATS_SOLVER_RIL;
3484 }
3485 else
3486 {
3487 fprintf (stderr, "No solver given ...");
3488 res = 1;
3489 end_now ();
3490 return;
3491 }
3492
3493 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
3494 default_properties[c] = DEFAULT_REL_QUALITY;
3495
3496 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
3497 default_preferences[c] = DEFAULT_REL_PREFERENCE;
3498
3499 /* load experiment */
3500 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading experiment\n");
3501 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
3502 if (NULL == e)
3503 {
3504 fprintf (stderr, "Failed to load experiment ...\n");
3505 res = 1;
3506 end_now ();
3507 return;
3508 }
3509
3510 /* load solver */
3511 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Loading solver\n");
3512 sh = GNUNET_ATS_solvers_solver_start (solver);
3513 if (NULL == sh)
3514 {
3515 fprintf (stderr, "Failed to start solver ...\n");
3516 end_now ();
3517 res = 1;
3518 return;
3519 }
3520
3521 /* start logging */
3522 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Start logging \n");
3523 l = GNUNET_ATS_solver_logging_start (e->log_freq);
3524
3525 /* run experiment */
3526 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "=== Running experiment \n");
3527 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
3528 experiment_done_cb);
3529
3530 /* WAIT */
3531}
3532
3533
3534/**
3535 * Main function of the benchmark
3536 *
3537 * @param argc argument count
3538 * @param argv argument values
3539 */
3540int
3541main (int argc, char *argv[])
3542{
3543 opt_exp_file = NULL;
3544 opt_solver = NULL;
3545 opt_log = GNUNET_NO;
3546 opt_save = GNUNET_NO;
3547
3548 res = 0;
3549
3550 static struct GNUNET_GETOPT_CommandLineOption options[] = {
3551 GNUNET_GETOPT_option_string ('s',
3552 "solver",
3553 gettext_noop ("solver to use"),
3554 &opt_solver),
3555
3556 GNUNET_GETOPT_option_string ('e',
3557 "experiment"
3558 gettext_noop ("experiment to use"),
3559 &opt_exp_file),
3560
3561 GNUNET_GETOPT_option_verbose (&opt_verbose),
3562
3563 GNUNET_GETOPT_option_flag ('p',
3564 "print",
3565 gettext_noop ("print logging"),
3566 &opt_print),
3567
3568 GNUNET_GETOPT_option_flag ('f',
3569 "file",
3570 gettext_noop ("save logging to disk"),
3571 &opt_save),
3572
3573 GNUNET_GETOPT_option_flag ('d',
3574 "dn",
3575 gettext_noop ("disable normalization"),
3576 &opt_disable_normalization),
3577
3578 GNUNET_GETOPT_OPTION_END
3579 };
3580
3581 GNUNET_PROGRAM_run (argc, argv, "gnunet-ats-solver-eval",
3582 NULL, options, &run, argv[0]);
3583
3584 return res;
3585}
3586
3587
3588/* end of file ats-testing-experiment.c*/