2 This file is part of GNUnet.
3 Copyright (C) 2010-2013, 2016 GNUnet e.V.
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.
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.
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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file ats-tests/ats-testing-traffic.c
22 * @brief ats benchmark: traffic generator
23 * @author Christian Grothoff
24 * @author Matthias Wachs
27 #include "gnunet_util_lib.h"
28 #include "ats-testing.h"
30 static struct TrafficGenerator *tg_head;
31 static struct TrafficGenerator *tg_tail;
33 extern struct GNUNET_ATS_TEST_Topology *top;
35 static struct GNUNET_TIME_Relative
36 get_delay (struct TrafficGenerator *tg)
38 struct GNUNET_TIME_Relative delay;
39 struct GNUNET_TIME_Relative time_delta;
40 long long int cur_rate;
41 long long int delta_rate;
43 delay.rel_value_us = 0;
45 /* Calculate the current transmission rate based on the type of traffic */
47 case GNUNET_ATS_TEST_TG_CONSTANT:
48 if (UINT32_MAX == tg->base_rate)
49 return GNUNET_TIME_UNIT_ZERO;
50 cur_rate = tg->base_rate;
52 case GNUNET_ATS_TEST_TG_LINEAR:
53 time_delta = GNUNET_TIME_absolute_get_duration(tg->time_start);
54 /* Calculate point of time in the current period */
55 time_delta.rel_value_us = time_delta.rel_value_us % tg->duration_period.rel_value_us;
56 delta_rate = ((double) time_delta.rel_value_us / tg->duration_period.rel_value_us) *
57 (tg->max_rate - tg->base_rate);
58 if ((tg->max_rate < tg->base_rate) && ((tg->max_rate - tg->base_rate) > tg->base_rate))
60 /* This will cause an underflow */
63 cur_rate = tg->base_rate + delta_rate;
65 case GNUNET_ATS_TEST_TG_RANDOM:
66 cur_rate = tg->base_rate + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
67 tg->max_rate - tg->base_rate);
69 case GNUNET_ATS_TEST_TG_SINUS:
70 time_delta = GNUNET_TIME_absolute_get_duration(tg->time_start);
71 /* Calculate point of time in the current period */
72 time_delta.rel_value_us = time_delta.rel_value_us % tg->duration_period.rel_value_us;
73 if ((tg->max_rate - tg->base_rate) > tg->base_rate)
75 /* This will cause an underflow for second half of sinus period,
76 * will be detected in general when experiments are loaded */
79 delta_rate = (tg->max_rate - tg->base_rate) *
80 sin ( (2 * M_PI) / ((double) tg->duration_period.rel_value_us) * time_delta.rel_value_us);
81 cur_rate = tg->base_rate + delta_rate;
92 /* Calculate the delay for the next message based on the current delay */
93 delay.rel_value_us = GNUNET_TIME_UNIT_SECONDS.rel_value_us * TEST_MESSAGE_SIZE / cur_rate;
95 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
96 "Current rate is %lld, calculated delay is %llu\n",
98 (unsigned long long) delay.rel_value_us);
104 update_ping_data (void *cls)
106 struct BenchmarkPartner *p = cls;
107 struct GNUNET_TIME_Relative delay;
110 p->bytes_sent += TEST_MESSAGE_SIZE;
111 p->me->total_messages_sent++;
112 p->me->total_bytes_sent += TEST_MESSAGE_SIZE;
119 delay = get_delay (p->tg);
120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
121 "Delay for next transmission %s\n",
122 GNUNET_STRINGS_relative_time_to_string (delay,
124 p->tg->next_ping_transmission
125 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
131 comm_schedule_send (void *cls)
133 struct BenchmarkPartner *p = cls;
134 struct TestMessage *msg;
135 struct GNUNET_MQ_Envelope *env;
137 p->tg->send_task = NULL;
138 p->last_message_sent = GNUNET_TIME_absolute_get();
139 env = GNUNET_MQ_msg (msg,
140 TEST_MESSAGE_TYPE_PING);
141 memset (msg->padding,
143 sizeof (msg->padding));
144 GNUNET_MQ_notify_sent (env,
147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148 "Master [%u]: Sending PING to [%u]\n",
151 GNUNET_MQ_send (p->mq,
157 update_pong_data (void *cls)
159 struct BenchmarkPartner *p = cls;
162 p->bytes_sent += TEST_MESSAGE_SIZE;
163 p->me->total_messages_sent++;
164 p->me->total_bytes_sent += TEST_MESSAGE_SIZE;
169 GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p)
171 struct TestMessage *msg;
172 struct GNUNET_MQ_Envelope *env;
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
175 "Slave [%u]: Received PING from [%u], sending PONG\n",
178 p->messages_received++;
179 p->bytes_received += TEST_MESSAGE_SIZE;
180 p->me->total_messages_received++;
181 p->me->total_bytes_received += TEST_MESSAGE_SIZE;
184 env = GNUNET_MQ_msg (msg,
185 TEST_MESSAGE_TYPE_PING);
186 memset (msg->padding,
188 sizeof (msg->padding));
189 GNUNET_MQ_notify_sent (env,
192 GNUNET_MQ_send (p->mq,
198 GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p)
200 struct GNUNET_TIME_Relative left;
201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
202 "Master [%u]: Received PONG from [%u], next message\n",
206 p->messages_received++;
207 p->bytes_received += TEST_MESSAGE_SIZE;
208 p->me->total_messages_received++;
209 p->me->total_bytes_received += TEST_MESSAGE_SIZE;
210 p->total_app_rtt += GNUNET_TIME_absolute_get_difference(p->last_message_sent,
211 GNUNET_TIME_absolute_get()).rel_value_us;
213 /* Schedule next send event */
217 left = GNUNET_TIME_absolute_get_remaining(p->tg->next_ping_transmission);
218 if (UINT32_MAX == p->tg->base_rate)
220 p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
222 else if (0 == left.rel_value_us)
224 p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
228 /* Enforce minimum transmission rate 1 msg / sec */
229 if (GNUNET_TIME_UNIT_SECONDS.rel_value_us == (left = GNUNET_TIME_relative_min (left, GNUNET_TIME_UNIT_SECONDS)).rel_value_us)
230 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
231 "Enforcing minimum send rate between master [%u] and slave [%u]\n",
232 p->me->no, p->dest->no);
233 p->tg->send_task = GNUNET_SCHEDULER_add_delayed (left,
234 &comm_schedule_send, p);
240 * Generate between the source master and the partner and send traffic with a
243 * @param src traffic source
244 * @param dest traffic partner
245 * @param type type of traffic to generate
246 * @param base_rate traffic base rate to send data with
247 * @param max_rate traffic maximum rate to send data with
248 * @param period duration of a period of traffic generation (~ 1/frequency)
249 * @param duration how long to generate traffic
250 * @return the traffic generator
252 struct TrafficGenerator *
253 GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
254 struct BenchmarkPartner *dest,
255 enum GeneratorType type,
256 unsigned int base_rate,
257 unsigned int max_rate,
258 struct GNUNET_TIME_Relative period,
259 struct GNUNET_TIME_Relative duration)
261 struct TrafficGenerator *tg;
263 if (NULL != dest->tg)
269 tg = GNUNET_new (struct TrafficGenerator);
270 GNUNET_CONTAINER_DLL_insert (tg_head,
276 tg->base_rate = base_rate;
277 tg->max_rate = max_rate;
278 tg->duration_period = period;
279 tg->time_start = GNUNET_TIME_absolute_get();
280 tg->next_ping_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
283 case GNUNET_ATS_TEST_TG_CONSTANT:
284 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
285 "Setting up constant traffic generator master[%u] `%s' and slave [%u] `%s' max %u Bips\n",
287 GNUNET_i2s (&dest->me->id),
289 GNUNET_i2s (&dest->dest->id),
292 case GNUNET_ATS_TEST_TG_LINEAR:
293 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
294 "Setting up linear traffic generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bips\n",
296 GNUNET_i2s (&dest->me->id),
298 GNUNET_i2s (&dest->dest->id),
302 case GNUNET_ATS_TEST_TG_SINUS:
303 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
304 "Setting up sinus traffic generator master[%u] `%s' and slave [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
306 GNUNET_i2s (&dest->me->id),
308 GNUNET_i2s (&dest->dest->id),
312 case GNUNET_ATS_TEST_TG_RANDOM:
313 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
314 "Setting up random traffic generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bps\n",
316 GNUNET_i2s (&dest->me->id),
318 GNUNET_i2s (&dest->dest->id),
328 = GNUNET_SCHEDULER_add_now (&comm_schedule_send,
335 GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg)
337 GNUNET_CONTAINER_DLL_remove (tg_head,
341 if (NULL != tg->send_task)
343 GNUNET_SCHEDULER_cancel (tg->send_task);
344 tg->send_task = NULL;
351 * Stop all traffic generators
354 GNUNET_ATS_TEST_generate_traffic_stop_all ()
356 struct TrafficGenerator *cur;
357 struct TrafficGenerator *next;
360 for (cur = next; NULL != cur; cur = next)
363 GNUNET_ATS_TEST_generate_traffic_stop(cur);
367 /* end of file ats-testing-traffic.c */