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