preference generation implemented
[oweals/gnunet.git] / src / ats / gnunet-ats-solver-eval.h
1 /*
2  This file is part of GNUnet.
3  (C) 2010-2013 Christian Grothoff (and other contributing authors)
4
5  GNUnet is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published
7  by the Free Software Foundation; either version 3, or (at your
8  option) any later version.
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  General Public License for more details.
14
15  You should have received a copy of the GNU General Public License
16  along with GNUnet; see the file COPYING.  If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  Boston, MA 02111-1307, USA.
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_plugin.h"
29 #include "gnunet_ats_service.h"
30 #include "gnunet-service-ats_addresses.h"
31 #include "gnunet-service-ats_normalization.h"
32 #include "test_ats_api_common.h"
33
34 enum GeneratorType
35 {
36   GNUNET_ATS_TEST_TG_LINEAR,
37   GNUNET_ATS_TEST_TG_CONSTANT,
38   GNUNET_ATS_TEST_TG_RANDOM,
39   GNUNET_ATS_TEST_TG_SINUS
40 };
41
42
43 enum OperationType
44 {
45   SOLVER_OP_ADD_ADDRESS,
46   SOLVER_OP_DEL_ADDRESS,
47   SOLVER_OP_START_SET_PROPERTY,
48   SOLVER_OP_STOP_SET_PROPERTY,
49   SOLVER_OP_START_SET_PREFERENCE,
50   SOLVER_OP_STOP_SET_PREFERENCE
51 };
52
53 struct Episode;
54
55 struct Experiment;
56
57 typedef void (*GNUNET_ATS_TESTING_EpisodeDoneCallback) (
58     struct Episode *e);
59
60 typedef void (*GNUNET_ATS_TESTING_ExperimentDoneCallback) (struct Experiment *e,
61     struct GNUNET_TIME_Relative duration,int success);
62
63 /**
64  * An operation in an experiment
65  */
66 struct GNUNET_ATS_TEST_Operation
67 {
68   struct GNUNET_ATS_TEST_Operation *next;
69   struct GNUNET_ATS_TEST_Operation *prev;
70
71   long long unsigned int address_id;
72   long long unsigned int peer_id;
73   long long unsigned int address_session;
74   long long unsigned int address_network;
75   char*address;
76   char*plugin;
77
78
79   long long unsigned int base_rate;
80   long long unsigned int max_rate;
81   struct GNUNET_TIME_Relative period;
82   struct GNUNET_TIME_Relative frequency;
83
84   enum OperationType type;
85   enum GeneratorType tg_type;
86   enum GNUNET_ATS_PreferenceKind pref_type;
87   enum GNUNET_ATS_Property prop_type;
88 };
89
90 struct Episode
91 {
92   int id;
93   struct Episode *next;
94   struct GNUNET_TIME_Relative duration;
95
96   struct GNUNET_ATS_TEST_Operation *head;
97   struct GNUNET_ATS_TEST_Operation *tail;
98 };
99
100
101 struct Experiment
102 {
103   char *name;
104   char *cfg_file;
105   unsigned long long int num_masters;
106   unsigned long long int num_slaves;
107   struct GNUNET_TIME_Relative log_freq;
108   struct GNUNET_TIME_Relative max_duration;
109   struct GNUNET_TIME_Relative total_duration;
110   struct GNUNET_TIME_Absolute start_time;
111   unsigned int num_episodes;
112   struct Episode *start;
113
114   struct GNUNET_CONFIGURATION_Handle *cfg;
115
116   GNUNET_SCHEDULER_TaskIdentifier experiment_timeout_task;
117   GNUNET_SCHEDULER_TaskIdentifier episode_timeout_task;
118   struct Episode *cur;
119
120   GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb;
121   GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb;
122 };
123
124 struct PreferenceGenerator
125 {
126   struct PreferenceGenerator *prev;
127   struct PreferenceGenerator *next;
128
129   enum GeneratorType type;
130
131   unsigned int peer;
132   unsigned int address_id;
133
134   enum GNUNET_ATS_PreferenceKind kind;
135
136   long int base_value;
137   long int max_value;
138   struct GNUNET_TIME_Relative duration_period;
139   struct GNUNET_TIME_Relative frequency;
140
141   GNUNET_SCHEDULER_TaskIdentifier set_task;
142   struct GNUNET_TIME_Absolute next_ping_transmission;
143   struct GNUNET_TIME_Absolute time_start;
144 };
145
146
147
148 /* LEGACY */
149
150 #if 0
151 #define TEST_ATS_PREFERENCE_DEFAULT 1.0
152
153 /**
154  * Message type sent for traffic generation
155  */
156 #define TEST_MESSAGE_TYPE_PING 12345
157
158 /**
159  * Message type sent as response during traffic generation
160  */
161 #define TEST_MESSAGE_TYPE_PONG 12346
162
163 /**
164  * Size of test messages
165  */
166 #define TEST_MESSAGE_SIZE 100
167
168 struct BenchmarkPartner;
169
170 struct BenchmarkPeer;
171
172 struct GNUNET_ATS_TEST_Topology;
173
174 struct TrafficGenerator;
175
176
177
178
179
180 /**
181  * Callback to call when topology setup is completed
182  *
183  * @param cls the closure
184  * @param masters array of master peers
185  * @param slaves array of master peers
186  */
187 typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (void *cls,
188     struct BenchmarkPeer *masters,
189     struct BenchmarkPeer *slaves);
190
191 /**
192  * Callback called when logging is required for the data contained
193  *
194  * @param cls the closure
195  * @param address an address
196  * @param address_active is address active
197  * @param bandwidth_out bandwidth outbound
198  * @param bandwidth_in bandwidth inbound
199  * @param ats ats information
200  * @param ats_count number of ats inforation
201  */
202 typedef void
203 (*GNUNET_ATS_TEST_LogRequest) (void *cls,
204     const struct GNUNET_HELLO_Address *address_id,
205     int address_active,
206     struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
207     struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
208     const struct GNUNET_ATS_Information *ats,
209     uint32_t ats_count);
210
211 /**
212  * Information we track for a peer in the testbed.
213  */
214 struct BenchmarkPeer
215 {
216   /**
217    * Handle with testbed.
218    */
219   struct GNUNET_TESTBED_Peer *peer;
220
221   /**
222    * Unique identifier
223    */
224   int no;
225
226   /**
227    * Is this peer a measter: GNUNET_YES/GNUNET_NO
228    */
229   int master;
230
231   /**
232    *  Peer ID
233    */
234   struct GNUNET_PeerIdentity id;
235
236   /**
237    * Testbed operation to get peer information
238    */
239   struct GNUNET_TESTBED_Operation *peer_id_op;
240
241   /**
242    * Testbed operation to connect to ATS performance service
243    */
244   struct GNUNET_TESTBED_Operation *ats_perf_op;
245
246   /**
247    * Testbed operation to connect to core
248    */
249   struct GNUNET_TESTBED_Operation *comm_op;
250
251   /**
252    * ATS performance handle
253    */
254   struct GNUNET_ATS_PerformanceHandle *ats_perf_handle;
255
256   /**
257    * Masters only:
258    * Testbed connect operations to connect masters to slaves
259    */
260   struct TestbedConnectOperation *core_connect_ops;
261
262   /**
263    *  Core handle
264    */
265   struct GNUNET_CORE_Handle *ch;
266
267   /**
268    *  Core handle
269    */
270   struct GNUNET_TRANSPORT_Handle *th;
271
272   /**
273    * Masters only:
274    * Peer to set ATS preferences for
275    */
276   struct BenchmarkPeer *pref_partner;
277
278   /**
279    * Masters only
280    * Progress task
281    */
282   GNUNET_SCHEDULER_TaskIdentifier ats_task;
283
284   /**
285    * Masters only
286    * Progress task
287    */
288   double pref_value;
289
290   /**
291    * Array of partners with num_slaves entries (if master) or
292    * num_master entries (if slave)
293    */
294   struct BenchmarkPartner *partners;
295
296   /**
297    * Number of partners
298    */
299   int num_partners;
300
301   /**
302    * Number of core connections
303    */
304   int core_connections;
305
306   /**
307    * Masters only:
308    * Number of connections to slave peers
309    */
310   int core_slave_connections;
311
312   /**
313    * Total number of messages this peer has sent
314    */
315   unsigned int total_messages_sent;
316
317   /**
318    * Total number of bytes this peer has sent
319    */
320   unsigned int total_bytes_sent;
321
322   /**
323    * Total number of messages this peer has received
324    */
325   unsigned int total_messages_received;
326
327   /**
328    * Total number of bytes this peer has received
329    */
330   unsigned int total_bytes_received;
331 };
332
333 struct TrafficGenerator
334 {
335   struct TrafficGenerator *prev;
336   struct TrafficGenerator *next;
337
338   enum GeneratorType type;
339
340   struct BenchmarkPeer *src;
341   struct BenchmarkPartner *dest;
342
343   long int base_rate;
344   long int max_rate;
345   struct GNUNET_TIME_Relative duration_period;
346
347   GNUNET_SCHEDULER_TaskIdentifier send_task;
348   struct GNUNET_TIME_Absolute next_ping_transmission;
349   struct GNUNET_TIME_Absolute time_start;
350 };
351
352
353 struct PreferenceGenerator
354 {
355   struct PreferenceGenerator *prev;
356   struct PreferenceGenerator *next;
357
358   enum GeneratorType type;
359
360   struct BenchmarkPeer *src;
361   struct BenchmarkPartner *dest;
362
363   enum GNUNET_ATS_PreferenceKind kind;
364
365   long int base_value;
366   long int max_value;
367   struct GNUNET_TIME_Relative duration_period;
368   struct GNUNET_TIME_Relative frequency;
369
370   GNUNET_SCHEDULER_TaskIdentifier set_task;
371   struct GNUNET_TIME_Absolute next_ping_transmission;
372   struct GNUNET_TIME_Absolute time_start;
373 };
374
375 /**
376  * Information about a benchmarking partner
377  */
378 struct BenchmarkPartner
379 {
380   /**
381    * The peer itself this partner belongs to
382    */
383   struct BenchmarkPeer *me;
384
385   /**
386    * The partner peer
387    */
388   struct BenchmarkPeer *dest;
389
390   /**
391    * Core transmit handles
392    */
393   struct GNUNET_CORE_TransmitHandle *cth;
394
395   /**
396    * Transport transmit handles
397    */
398   struct GNUNET_TRANSPORT_TransmitHandle *tth;
399
400   struct TrafficGenerator *tg;
401   struct PreferenceGenerator *pg;
402
403   /**
404    * Timestamp to calculate communication layer delay
405    */
406   struct GNUNET_TIME_Absolute last_message_sent;
407
408   /**
409    * Accumulated RTT for all messages
410    */
411   unsigned int total_app_rtt;
412
413   /**
414    * Number of messages sent to this partner
415    */
416   unsigned int messages_sent;
417
418   /**
419    * Number of bytes sent to this partner
420    */
421   unsigned int bytes_sent;
422
423   /**
424    * Number of messages received from this partner
425    */
426   unsigned int messages_received;
427
428   /**
429    * Number of bytes received from this partner
430    */
431   unsigned int bytes_received;
432
433   /* Current ATS properties */
434
435   uint32_t ats_distance;
436
437   uint32_t ats_delay;
438
439   uint32_t bandwidth_in;
440
441   uint32_t bandwidth_out;
442
443   uint32_t ats_utilization_up;
444
445   uint32_t ats_utilization_down;
446
447   uint32_t ats_network_type;
448
449   uint32_t ats_cost_wan;
450
451   uint32_t ats_cost_lan;
452
453   uint32_t ats_cost_wlan;
454
455   double pref_bandwidth;
456   double pref_delay;
457 };
458
459 /**
460  * Overall state of the performance benchmark
461  */
462 struct BenchmarkState
463 {
464   /**
465    * Are we connected to ATS service of all peers: GNUNET_YES/NO
466    */
467   int connected_ATS_service;
468
469   /**
470    * Are we connected to CORE service of all peers: GNUNET_YES/NO
471    */
472   int connected_COMM_service;
473
474   /**
475    * Are we connected to all peers: GNUNET_YES/NO
476    */
477   int connected_PEERS;
478
479   /**
480    * Are we connected to all slave peers on CORE level: GNUNET_YES/NO
481    */
482   int connected_CORE;
483
484   /**
485    * Are we connected to CORE service of all peers: GNUNET_YES/NO
486    */
487   int benchmarking;
488 };
489
490
491 struct GNUNET_ATS_TEST_Topology
492 {
493   /**
494    * Shutdown task
495    */
496   GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
497
498   /**
499    * Progress task
500    */
501   GNUNET_SCHEDULER_TaskIdentifier progress_task;
502
503   /**
504    * Test result
505    */
506   int result;
507
508   /**Test core (GNUNET_YES) or transport (GNUNET_NO)
509    */
510   int test_core;
511
512   /**
513    * Solver string
514    */
515   char *solver;
516
517   /**
518    * Preference string
519    */
520   char *testname;
521
522   /**
523    * Preference string
524    */
525   char *pref_str;
526
527   /**
528    * ATS preference value
529    */
530   int pref_val;
531
532   /**
533    * Number master peers
534    */
535   unsigned int num_masters;
536
537   /**
538    * Array of master peers
539    */
540   struct BenchmarkPeer *mps;
541
542   /**
543    * Number slave peers
544    */
545   unsigned int num_slaves;
546
547   /**
548    * Array of slave peers
549    */
550   struct BenchmarkPeer *sps;
551
552   /**
553    * Benchmark duration
554    */
555   struct GNUNET_TIME_Relative perf_duration;
556
557   /**
558    * Logging frequency
559    */
560   struct GNUNET_TIME_Relative log_frequency;
561
562   /**
563    * Benchmark state
564    */
565   struct BenchmarkState state;
566
567   struct GNUNET_CORE_MessageHandler *handlers;
568
569   GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb;
570
571   GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb;
572   GNUNET_ATS_AddressInformationCallback ats_perf_cb;
573   void *done_cb_cls;
574 };
575
576
577
578 /*
579  * Experiment related functions
580  */
581
582
583 /**
584  * Execute the specified experiment
585  *
586  * @param e the Experiment
587  * @param ep_done_cb a episode is completed
588  * @param e_done_cb the experiment is completed
589  */
590 void
591 GNUNET_ATS_TEST_experimentation_run (struct Experiment *e,
592     GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
593     GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb);
594
595 /**
596  * Load an experiment from a file
597  *
598  * @param filename the file
599  * @return the Experiment or NULL on failure
600  */
601 struct Experiment *
602 GNUNET_ATS_TEST_experimentation_load (char *filename);
603
604
605 /**
606  * Stop an experiment
607  *
608  * @param e the experiment
609  */
610 void
611 GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e);
612
613 /*
614  * Traffic related functions
615  */
616
617 void
618 GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p);
619
620 void
621 GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p);
622
623
624 /**
625  * Generate between the source master and the partner and send traffic with a
626  * maximum rate.
627  *
628  * @param src traffic source
629  * @param dest traffic partner
630  * @param type type of traffic to generate
631  * @param base_rate traffic base rate to send data with
632  * @param max_rate  traffic maximum rate to send data with
633  * @param period duration of a period of traffic generation (~ 1/frequency)
634  * @param duration how long to generate traffic
635  * @return the traffic generator
636  */
637 struct TrafficGenerator *
638 GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
639     struct BenchmarkPartner *dest,
640     enum GeneratorType type,
641     long int base_rate,
642     long int max_rate,
643     struct GNUNET_TIME_Relative period,
644     struct GNUNET_TIME_Relative duration);
645
646 void
647 GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg);
648
649 /**
650  * Stop all traffic generators
651  */
652 void
653 GNUNET_ATS_TEST_generate_traffic_stop_all ();
654
655 struct PreferenceGenerator *
656 GNUNET_ATS_TEST_generate_preferences_start (struct BenchmarkPeer *src,
657     struct BenchmarkPartner *dest,
658     enum GeneratorType type,
659     long int base_value,
660     long int value_rate,
661     struct GNUNET_TIME_Relative period,
662     struct GNUNET_TIME_Relative frequency,
663     enum GNUNET_ATS_PreferenceKind kind);
664
665 void
666 GNUNET_ATS_TEST_generate_preferences_stop (struct PreferenceGenerator *pg);
667
668 void
669 GNUNET_ATS_TEST_generate_preferences_stop_all ();
670
671 /*
672  * Logging related functions
673  */
674
675
676
677 /*
678  * Topology related functions
679  */
680
681 struct BenchmarkPeer *
682 GNUNET_ATS_TEST_get_peer (int src);
683
684 struct BenchmarkPartner *
685 GNUNET_ATS_TEST_get_partner (int src, int dest);
686
687 /**
688  * Create a topology for ats testing
689  *
690  * @param name test name
691  * @param cfg_file configuration file to use for the peers
692  * @param num_slaves number of slaves
693  * @param num_masters number of masters
694  * @param test_core connect to CORE service (GNUNET_YES) or transport (GNUNET_NO)
695  * @param done_cb function to call when topology is setup
696  * @param done_cb_cls cls for callback
697  * @param recv_cb callback to call when data are received
698  * @param perf_cb callback to call when performance info are received
699  */
700 void
701 GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file,
702     unsigned int num_slaves,
703     unsigned int num_masters,
704     int test_core,
705     GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb,
706     void *done_cb_cls,
707     GNUNET_TRANSPORT_ReceiveCallback recv_cb,
708     GNUNET_ATS_TEST_LogRequest ats_perf_cb);
709
710 /**
711  * Shutdown topology
712  */
713 void
714 GNUNET_ATS_TEST_shutdown_topology (void);
715 #endif
716 /* end of file ats-testing.h */