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