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