GNUnet  0.11.x
gnunet-ats-sim.c
Go to the documentation of this file.
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  */
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_testbed_service.h"
31 #include "gnunet_ats_service.h"
32 #include "gnunet_core_service.h"
33 #include "ats-testing.h"
34 
35 #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
36  10)
37 
38 static struct BenchmarkPeer *masters_p;
39 static struct BenchmarkPeer *slaves_p;
40 
44 static char *opt_exp_file;
45 
49 static int opt_log;
50 
54 static int opt_plot;
55 
59 static int opt_verbose;
60 
62 
63 static struct Experiment *e;
64 
65 static struct LoggingHandle *l;
66 
67 
68 static void
69 evaluate (struct GNUNET_TIME_Relative duration_total)
70 {
71  int c_m;
72  int c_s;
73  unsigned int duration;
74  struct BenchmarkPeer *mp;
75  struct BenchmarkPartner *p;
76 
77  unsigned int b_sent_sec;
78  double kb_sent_percent;
79  unsigned int b_recv_sec;
80  double kb_recv_percent;
81  unsigned int rtt;
82 
83 
84  duration = (duration_total.rel_value_us / (1000 * 1000));
85  if (0 == duration)
86  duration = 1;
87  for (c_m = 0; c_m < e->num_masters; c_m++)
88  {
89  mp = &masters_p[c_m];
90  fprintf (stderr,
91  _ (
92  "Master [%u]: sent: %u KiB in %u sec. = %u KiB/s, received: %u KiB in %u sec. = %u KiB/s\n"),
93  mp->no, mp->total_bytes_sent / 1024,
94  duration,
95  (mp->total_bytes_sent / 1024) / duration,
96  mp->total_bytes_received / 1024,
97  duration,
98  (mp->total_bytes_received / 1024) / duration);
99 
100  for (c_s = 0; c_s < e->num_slaves; c_s++)
101  {
102  p = &mp->partners[c_s];
103 
104  b_sent_sec = 0;
105  b_recv_sec = 0;
106  kb_sent_percent = 0.0;
107  kb_recv_percent = 0.0;
108  rtt = 0;
109 
110  if (duration > 0)
111  {
112  b_sent_sec = p->bytes_sent / duration;
113  b_recv_sec = p->bytes_received / duration;
114  }
115 
116  if (mp->total_bytes_sent > 0)
117  kb_sent_percent = ((double) p->bytes_sent * 100) / mp->total_bytes_sent;
118  if (mp->total_bytes_received > 0)
119  kb_recv_percent = ((double) p->bytes_received * 100)
120  / mp->total_bytes_received;
121  if (1000 * p->messages_sent > 0)
122  rtt = p->total_app_rtt / (1000 * p->messages_sent);
123  fprintf (stderr,
124  "%c Master [%u] -> Slave [%u]: sent %u Bips (%.2f %%), received %u Bips (%.2f %%)\n",
125  (mp->pref_partner == p->dest) ? '*' : ' ',
126  mp->no, p->dest->no,
127  b_sent_sec, kb_sent_percent,
128  b_recv_sec, kb_recv_percent);
129  fprintf (stderr,
130  "%c Master [%u] -> Slave [%u]: Average application layer RTT: %u ms\n",
131  (mp->pref_partner == p->dest) ? '*' : ' ',
132  mp->no, p->dest->no, rtt);
133  }
134  }
135 }
136 
137 
138 static void
139 do_shutdown (void *cls)
140 {
141  fprintf (stderr, "Shutdown\n");
142  if (NULL != timeout_task)
143  {
144  GNUNET_SCHEDULER_cancel (timeout_task);
145  timeout_task = NULL;
146  }
147  if (NULL != l)
148  {
151  l = NULL;
152  }
153 
154  /* Stop traffic generation */
156 
157  /* Stop all preference generations */
159 
160  if (NULL != e)
161  {
163  e = NULL;
164  }
166 }
167 
168 
169 static void
170 do_timeout (void *cls)
171 {
172  timeout_task = NULL;
174 }
175 
176 
177 static void
178 log_request__cb (void *cls,
179  const struct GNUNET_HELLO_Address *address,
180  int address_active,
183  const struct GNUNET_ATS_Properties *ats)
184 {
185  if (NULL != l)
186  {
187  // GNUNET_break (0);
188  // GNUNET_ATS_TEST_logging_now (l);
189  }
190 }
191 
192 
193 static void
196  int success)
197 {
198  if (GNUNET_OK == success)
200  "Experiment done successful in %s\n",
202  GNUNET_YES));
203  else
204  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
205 
206  /* Stop logging */
208 
209  /* Stop traffic generation */
211 
212  /* Stop all preference generations */
214 
215  evaluate (duration);
216  if (opt_log)
219 }
220 
221 
222 static void
224 {
226  "Episode %u done\n",
227  ep->id);
228 }
229 
230 
231 static void
233  struct BenchmarkPeer *masters,
234  struct BenchmarkPeer *slaves)
235 {
237  "Topology setup complete!\n");
238 
239  masters_p = masters;
240  slaves_p = slaves;
241 
243  e->name,
244  masters_p,
245  e->num_masters, e->num_slaves,
246  opt_verbose);
250 /*
251  GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
252  GNUNET_ATS_TEST_TG_CONSTANT, 1, 1, GNUNET_TIME_UNIT_SECONDS,
253  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
254  GNUNET_ATS_PREFERENCE_BANDWIDTH);
255  *//*
256  GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
257  GNUNET_ATS_TEST_TG_LINEAR, 1, 50,
258  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2),
259  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
260  GNUNET_ATS_PREFERENCE_BANDWIDTH);
261  *//*
262  GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
263  GNUNET_ATS_TEST_TG_RANDOM, 1, 50,
264  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2),
265  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
266  GNUNET_ATS_PREFERENCE_BANDWIDTH);
267  *//*
268  GNUNET_ATS_TEST_generate_preferences_start(&masters[0],&masters[0].partners[0],
269  GNUNET_ATS_TEST_TG_SINUS, 10, 5,
270  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5),
271  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250),
272  GNUNET_ATS_PREFERENCE_BANDWIDTH);
273  */
274 #if 0
275  int c_m;
276  int c_s;
277  for (c_m = 0; c_m < e->num_masters; c_m++)
278  {
279  for (c_s = 0; c_s < e->num_slaves; c_s++)
280  {
281  /* Generate maximum traffic to all peers */
282  /* Example: Generate traffic with constant 10,000 Bytes/s */
284  &masters[c_m].partners[c_s],
286  10000,
288  /* Example: Generate traffic with an increasing rate from 1000 to 2000
289  * Bytes/s with in a minute */
291  &masters[c_m].partners[c_s],
293  1000,
294  2000,
297  /* Example: Generate traffic with a random rate between 1000 to 2000
298  * Bytes/s */
300  &masters[c_m].partners[c_s],
302  1000,
303  2000,
306  /* Example: Generate traffic with a sinus form, a base rate of
307  * 1000 Bytes/s, an amplitude of (max-base), and a period of 1 minute */
309  &masters[c_m].partners[c_s],
311  1000,
312  2000,
315  }
316  }
317 #endif
318 
319  timeout_task
322  e->max_duration),
323  &do_timeout,
324  NULL);
326 }
327 
328 
329 static void
330 parse_args (int argc, char *argv[])
331 {
332  int c;
333 
334  opt_exp_file = NULL;
335  opt_log = GNUNET_NO;
337 
338  for (c = 0; c < argc; c++)
339  {
340  if ((c < (argc - 1)) && (0 == strcmp (argv[c], "-e")))
341  {
343  opt_exp_file = GNUNET_strdup (argv[c + 1]);
344  }
345  if (0 == strcmp (argv[c], "-l"))
346  {
348  }
349  if (0 == strcmp (argv[c], "-p"))
350  {
352  }
353  if (0 == strcmp (argv[c], "-v"))
354  {
356  }
357  }
358 }
359 
360 
361 int
362 main (int argc, char *argv[])
363 {
364  GNUNET_log_setup ("gnunet-ats-sim", "INFO", NULL);
365 
366  parse_args (argc, argv);
367  if (NULL == opt_exp_file)
368  {
369  fprintf (stderr, "No experiment given...\n");
370  return 1;
371  }
372 
373  fprintf (stderr, "Loading experiment `%s' \n", opt_exp_file);
375  if (NULL == e)
376  {
377  fprintf (stderr, "Invalid experiment\n");
378  return 1;
379  }
380  if (0 == e->num_episodes)
381  {
382  fprintf (stderr, "No episodes included\n");
383  return 1;
384  }
385 
386  /* Setup a topology with */
387  GNUNET_ATS_TEST_create_topology ("gnunet-ats-sim", e->cfg_file,
388  e->num_slaves,
389  e->num_masters,
390  GNUNET_NO,
392  NULL,
393  &log_request__cb);
395  return 0;
396 }
397 
398 
399 /* end of file gnunet-ats-sim.c */
unsigned int total_bytes_sent
Total number of bytes this peer has sent.
Definition: ats-testing.h:217
unsigned int messages_sent
Number of messages sent to this partner.
Definition: ats-testing.h:315
unsigned int total_bytes_received
Total number of bytes this peer has received.
Definition: ats-testing.h:227
void GNUNET_ATS_TEST_experimentation_run(struct Experiment *e, GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb, GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
Execute the specified experiment.
uint64_t rel_value_us
The actual value.
struct Experiment * GNUNET_ATS_TEST_experimentation_load(const char *filename)
Load an experiment from a file.
static void do_shutdown(void *cls)
unsigned long long int num_masters
Definition: ats-testing.h:525
void GNUNET_ATS_TEST_logging_write_to_file(struct LoggingHandle *l, const char *experiment_name, int plots)
Write logging data to file.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
#define GNUNET_TIME_UNIT_MINUTES
One minute.
static char * opt_exp_file
cmd option -e: experiment file
struct BenchmarkPartner * partners
Array of partners with num_slaves entries (if master) or num_master entries (if slave) ...
Definition: ats-testing.h:191
static void do_timeout(void *cls)
static void evaluate(struct GNUNET_TIME_Relative duration_total)
unsigned int bytes_received
Number of bytes received from this partner.
Definition: ats-testing.h:330
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int main(int argc, char *argv[])
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static int opt_verbose
cmd option -v: verbose logs
unsigned int num_episodes
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct TrafficGenerator * GNUNET_ATS_TEST_generate_traffic_start(struct BenchmarkPeer *src, struct BenchmarkPartner *dest, enum GeneratorType type, unsigned int base_rate, unsigned int max_rate, struct GNUNET_TIME_Relative period, struct GNUNET_TIME_Relative duration)
Generate between the source master and the partner and send traffic with a maximum rate...
ATS performance characteristics for an address.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_TIME_Relative log_freq
struct LoggingHandle * GNUNET_ATS_TEST_logging_start(struct GNUNET_TIME_Relative log_frequency, const char *testname, struct BenchmarkPeer *masters, int num_masters, int num_slaves, int verbose)
Start logging.
static int opt_plot
cmd option -p: enable plots
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
int no
Unique identifier.
Definition: ats-testing.h:121
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
unsigned int total_app_rtt
Accumulated RTT for all messages.
Definition: ats-testing.h:310
void GNUNET_ATS_TEST_logging_stop(struct LoggingHandle *l)
Stop logging.
uint32_t bandwidth_in
Bandwidth assigned inbound.
Definition: ats-testing.h:340
Information we track for a peer in the testbed.
Definition: ats-testing.h:111
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:687
void GNUNET_ATS_TEST_logging_clean_up(struct LoggingHandle *l)
Clean up logging data.
unsigned long long int num_slaves
Definition: ats-testing.h:526
Information about a benchmarking partner.
Definition: ats-testing.h:275
static void parse_args(int argc, char *argv[])
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
uint32_t bandwidth_out
Bandwidth assigned outbound.
Definition: ats-testing.h:345
ats testing library: setup topology and provide logging to test ats
static struct GNUNET_ATS_PerformanceHandle * ats
Handle to the ATS performance subsystem.
static struct BenchmarkPeer * slaves_p
void GNUNET_ATS_TEST_shutdown_topology(void)
Shutdown topology.
Definition: ats-testing.c:967
32-bit bandwidth used for network exchange by GNUnet, in bytes per second.
void GNUNET_ATS_TEST_experimentation_stop(struct Experiment *e)
Stop an experiment.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:579
void GNUNET_ATS_TEST_generate_preferences_stop_all()
Stop all preferences generators.
unsigned int bytes_sent
Number of bytes sent to this partner.
Definition: ats-testing.h:320
static struct LoggingHandle * l
An address for communicating with a peer.
Automatic transport selection and outbound bandwidth determination.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
static struct GNUNET_TIME_Relative duration
How long do we run the test?
struct BenchmarkPeer * pref_partner
Masters only: Peer to set ATS preferences for.
Definition: ats-testing.h:173
static struct BenchmarkPeer * masters_p
static struct GNUNET_SCHEDULER_Task * timeout_task
void GNUNET_ATS_TEST_generate_traffic_stop_all()
Stop all traffic generators.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void topology_setup_done(void *cls, struct BenchmarkPeer *masters, struct BenchmarkPeer *slaves)
void GNUNET_ATS_TEST_create_topology(char *name, char *cfg_file, unsigned int num_slaves, unsigned int num_masters, int test_core, GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb, void *done_cb_cls, GNUNET_ATS_AddressInformationCallback log_request_cb)
Create a topology for ats testing.
Definition: ats-testing.c:927
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
struct GNUNET_TIME_Relative max_duration
static struct Experiment * e
static char * address
GNS address for this phone.
static int opt_log
cmd option -l: enable logging
struct BenchmarkPeer * dest
The partner peer.
Definition: ats-testing.h:285
static void episode_done_cb(struct Episode *ep)
#define GNUNET_free(ptr)
Wrapper around free.
static void log_request__cb(void *cls, const struct GNUNET_HELLO_Address *address, int address_active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, const struct GNUNET_ATS_Properties *ats)
Time for relative time used by GNUnet, in microseconds.
static void experiment_done_cb(struct Experiment *e, struct GNUNET_TIME_Relative duration, int success)
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966