diff options
Diffstat (limited to 'src/ats-tests/ats-testing-traffic.c')
-rw-r--r-- | src/ats-tests/ats-testing-traffic.c | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/src/ats-tests/ats-testing-traffic.c b/src/ats-tests/ats-testing-traffic.c deleted file mode 100644 index f19eac871..000000000 --- a/src/ats-tests/ats-testing-traffic.c +++ /dev/null | |||
@@ -1,393 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010-2013, 2016 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 | */ | ||
20 | /** | ||
21 | * @file ats-tests/ats-testing-traffic.c | ||
22 | * @brief ats benchmark: traffic generator | ||
23 | * @author Christian Grothoff | ||
24 | * @author Matthias Wachs | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "ats-testing.h" | ||
29 | |||
30 | static struct TrafficGenerator *tg_head; | ||
31 | static struct TrafficGenerator *tg_tail; | ||
32 | |||
33 | extern struct GNUNET_ATS_TEST_Topology *top; | ||
34 | |||
35 | static struct GNUNET_TIME_Relative | ||
36 | get_delay (struct TrafficGenerator *tg) | ||
37 | { | ||
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; | ||
42 | |||
43 | delay.rel_value_us = 0; | ||
44 | |||
45 | /* Calculate the current transmission rate based on the type of traffic */ | ||
46 | switch (tg->type) | ||
47 | { | ||
48 | case GNUNET_ATS_TEST_TG_CONSTANT: | ||
49 | if (UINT32_MAX == tg->base_rate) | ||
50 | return GNUNET_TIME_UNIT_ZERO; | ||
51 | cur_rate = tg->base_rate; | ||
52 | break; | ||
53 | |||
54 | case GNUNET_ATS_TEST_TG_LINEAR: | ||
55 | time_delta = GNUNET_TIME_absolute_get_duration (tg->time_start); | ||
56 | /* Calculate point of time in the current period */ | ||
57 | time_delta.rel_value_us = time_delta.rel_value_us | ||
58 | % tg->duration_period.rel_value_us; | ||
59 | delta_rate = ((double) time_delta.rel_value_us | ||
60 | / tg->duration_period.rel_value_us) | ||
61 | * (tg->max_rate - tg->base_rate); | ||
62 | if ((tg->max_rate < tg->base_rate) && ((tg->max_rate - tg->base_rate) > | ||
63 | tg->base_rate)) | ||
64 | { | ||
65 | /* This will cause an underflow */ | ||
66 | GNUNET_break (0); | ||
67 | } | ||
68 | cur_rate = tg->base_rate + delta_rate; | ||
69 | break; | ||
70 | |||
71 | case GNUNET_ATS_TEST_TG_RANDOM: | ||
72 | cur_rate = tg->base_rate + GNUNET_CRYPTO_random_u32 ( | ||
73 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
74 | tg->max_rate | ||
75 | - tg->base_rate); | ||
76 | break; | ||
77 | |||
78 | case GNUNET_ATS_TEST_TG_SINUS: | ||
79 | time_delta = GNUNET_TIME_absolute_get_duration (tg->time_start); | ||
80 | /* Calculate point of time in the current period */ | ||
81 | time_delta.rel_value_us = time_delta.rel_value_us | ||
82 | % tg->duration_period.rel_value_us; | ||
83 | if ((tg->max_rate - tg->base_rate) > tg->base_rate) | ||
84 | { | ||
85 | /* This will cause an underflow for second half of sinus period, | ||
86 | * will be detected in general when experiments are loaded */ | ||
87 | GNUNET_break (0); | ||
88 | } | ||
89 | delta_rate = (tg->max_rate - tg->base_rate) | ||
90 | * sin ((2 * M_PI) | ||
91 | / ((double) tg->duration_period.rel_value_us) | ||
92 | * time_delta.rel_value_us); | ||
93 | cur_rate = tg->base_rate + delta_rate; | ||
94 | break; | ||
95 | |||
96 | default: | ||
97 | return delay; | ||
98 | break; | ||
99 | } | ||
100 | |||
101 | if (cur_rate < 0) | ||
102 | { | ||
103 | cur_rate = 1; | ||
104 | } | ||
105 | /* Calculate the delay for the next message based on the current delay */ | ||
106 | delay.rel_value_us = GNUNET_TIME_UNIT_SECONDS.rel_value_us | ||
107 | * TEST_MESSAGE_SIZE / cur_rate; | ||
108 | |||
109 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
110 | "Current rate is %lld, calculated delay is %llu\n", | ||
111 | cur_rate, | ||
112 | (unsigned long long) delay.rel_value_us); | ||
113 | return delay; | ||
114 | } | ||
115 | |||
116 | |||
117 | static void | ||
118 | update_ping_data (void *cls) | ||
119 | { | ||
120 | struct BenchmarkPartner *p = cls; | ||
121 | struct GNUNET_TIME_Relative delay; | ||
122 | |||
123 | p->messages_sent++; | ||
124 | p->bytes_sent += TEST_MESSAGE_SIZE; | ||
125 | p->me->total_messages_sent++; | ||
126 | p->me->total_bytes_sent += TEST_MESSAGE_SIZE; | ||
127 | |||
128 | if (NULL == p->tg) | ||
129 | { | ||
130 | GNUNET_break (0); | ||
131 | return; | ||
132 | } | ||
133 | delay = get_delay (p->tg); | ||
134 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
135 | "Delay for next transmission %s\n", | ||
136 | GNUNET_STRINGS_relative_time_to_string (delay, | ||
137 | GNUNET_YES)); | ||
138 | p->tg->next_ping_transmission | ||
139 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
140 | delay); | ||
141 | } | ||
142 | |||
143 | |||
144 | static void | ||
145 | comm_schedule_send (void *cls) | ||
146 | { | ||
147 | struct BenchmarkPartner *p = cls; | ||
148 | struct TestMessage *msg; | ||
149 | struct GNUNET_MQ_Envelope *env; | ||
150 | |||
151 | p->tg->send_task = NULL; | ||
152 | p->last_message_sent = GNUNET_TIME_absolute_get (); | ||
153 | env = GNUNET_MQ_msg (msg, | ||
154 | TEST_MESSAGE_TYPE_PING); | ||
155 | memset (msg->padding, | ||
156 | 'a', | ||
157 | sizeof(msg->padding)); | ||
158 | GNUNET_MQ_notify_sent (env, | ||
159 | &update_ping_data, | ||
160 | p); | ||
161 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
162 | "Master [%u]: Sending PING to [%u]\n", | ||
163 | p->me->no, | ||
164 | p->dest->no); | ||
165 | GNUNET_MQ_send (p->mq, | ||
166 | env); | ||
167 | } | ||
168 | |||
169 | |||
170 | static void | ||
171 | update_pong_data (void *cls) | ||
172 | { | ||
173 | struct BenchmarkPartner *p = cls; | ||
174 | |||
175 | p->messages_sent++; | ||
176 | p->bytes_sent += TEST_MESSAGE_SIZE; | ||
177 | p->me->total_messages_sent++; | ||
178 | p->me->total_bytes_sent += TEST_MESSAGE_SIZE; | ||
179 | } | ||
180 | |||
181 | |||
182 | void | ||
183 | GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p) | ||
184 | { | ||
185 | struct TestMessage *msg; | ||
186 | struct GNUNET_MQ_Envelope *env; | ||
187 | |||
188 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
189 | "Slave [%u]: Received PING from [%u], sending PONG\n", | ||
190 | p->me->no, | ||
191 | p->dest->no); | ||
192 | p->messages_received++; | ||
193 | p->bytes_received += TEST_MESSAGE_SIZE; | ||
194 | p->me->total_messages_received++; | ||
195 | p->me->total_bytes_received += TEST_MESSAGE_SIZE; | ||
196 | |||
197 | |||
198 | env = GNUNET_MQ_msg (msg, | ||
199 | TEST_MESSAGE_TYPE_PING); | ||
200 | memset (msg->padding, | ||
201 | 'a', | ||
202 | sizeof(msg->padding)); | ||
203 | GNUNET_MQ_notify_sent (env, | ||
204 | &update_pong_data, | ||
205 | p); | ||
206 | GNUNET_MQ_send (p->mq, | ||
207 | env); | ||
208 | } | ||
209 | |||
210 | |||
211 | void | ||
212 | GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p) | ||
213 | { | ||
214 | struct GNUNET_TIME_Relative left; | ||
215 | |||
216 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
217 | "Master [%u]: Received PONG from [%u], next message\n", | ||
218 | p->me->no, | ||
219 | p->dest->no); | ||
220 | |||
221 | p->messages_received++; | ||
222 | p->bytes_received += TEST_MESSAGE_SIZE; | ||
223 | p->me->total_messages_received++; | ||
224 | p->me->total_bytes_received += TEST_MESSAGE_SIZE; | ||
225 | p->total_app_rtt += GNUNET_TIME_absolute_get_difference (p->last_message_sent, | ||
226 | GNUNET_TIME_absolute_get ()) | ||
227 | .rel_value_us; | ||
228 | |||
229 | /* Schedule next send event */ | ||
230 | if (NULL == p->tg) | ||
231 | return; | ||
232 | |||
233 | left = GNUNET_TIME_absolute_get_remaining (p->tg->next_ping_transmission); | ||
234 | if (UINT32_MAX == p->tg->base_rate) | ||
235 | { | ||
236 | p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p); | ||
237 | } | ||
238 | else if (0 == left.rel_value_us) | ||
239 | { | ||
240 | p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p); | ||
241 | } | ||
242 | else | ||
243 | { | ||
244 | /* Enforce minimum transmission rate 1 msg / sec */ | ||
245 | if (GNUNET_TIME_UNIT_SECONDS.rel_value_us == (left = | ||
246 | GNUNET_TIME_relative_min ( | ||
247 | left, | ||
248 | GNUNET_TIME_UNIT_SECONDS)) | ||
249 | .rel_value_us) | ||
250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
251 | "Enforcing minimum send rate between master [%u] and slave [%u]\n", | ||
252 | p->me->no, p->dest->no); | ||
253 | p->tg->send_task = GNUNET_SCHEDULER_add_delayed (left, | ||
254 | &comm_schedule_send, p); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | |||
259 | /** | ||
260 | * Generate between the source master and the partner and send traffic with a | ||
261 | * maximum rate. | ||
262 | * | ||
263 | * @param src traffic source | ||
264 | * @param dest traffic partner | ||
265 | * @param type type of traffic to generate | ||
266 | * @param base_rate traffic base rate to send data with | ||
267 | * @param max_rate traffic maximum rate to send data with | ||
268 | * @param period duration of a period of traffic generation (~ 1/frequency) | ||
269 | * @param duration how long to generate traffic | ||
270 | * @return the traffic generator | ||
271 | */ | ||
272 | struct TrafficGenerator * | ||
273 | GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src, | ||
274 | struct BenchmarkPartner *dest, | ||
275 | enum GeneratorType type, | ||
276 | unsigned int base_rate, | ||
277 | unsigned int max_rate, | ||
278 | struct GNUNET_TIME_Relative period, | ||
279 | struct GNUNET_TIME_Relative duration) | ||
280 | { | ||
281 | struct TrafficGenerator *tg; | ||
282 | |||
283 | if (NULL != dest->tg) | ||
284 | { | ||
285 | GNUNET_break (0); | ||
286 | return NULL; | ||
287 | } | ||
288 | |||
289 | tg = GNUNET_new (struct TrafficGenerator); | ||
290 | GNUNET_CONTAINER_DLL_insert (tg_head, | ||
291 | tg_tail, | ||
292 | tg); | ||
293 | tg->type = type; | ||
294 | tg->src = src; | ||
295 | tg->dest = dest; | ||
296 | tg->base_rate = base_rate; | ||
297 | tg->max_rate = max_rate; | ||
298 | tg->duration_period = period; | ||
299 | tg->time_start = GNUNET_TIME_absolute_get (); | ||
300 | tg->next_ping_transmission = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
301 | |||
302 | switch (type) | ||
303 | { | ||
304 | case GNUNET_ATS_TEST_TG_CONSTANT: | ||
305 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
306 | "Setting up constant traffic generator master[%u] `%s' and slave [%u] `%s' max %u Bips\n", | ||
307 | dest->me->no, | ||
308 | GNUNET_i2s (&dest->me->id), | ||
309 | dest->dest->no, | ||
310 | GNUNET_i2s (&dest->dest->id), | ||
311 | base_rate); | ||
312 | break; | ||
313 | |||
314 | case GNUNET_ATS_TEST_TG_LINEAR: | ||
315 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
316 | "Setting up linear traffic generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bips\n", | ||
317 | dest->me->no, | ||
318 | GNUNET_i2s (&dest->me->id), | ||
319 | dest->dest->no, | ||
320 | GNUNET_i2s (&dest->dest->id), | ||
321 | base_rate, | ||
322 | max_rate); | ||
323 | break; | ||
324 | |||
325 | case GNUNET_ATS_TEST_TG_SINUS: | ||
326 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
327 | "Setting up sinus traffic generator master[%u] `%s' and slave [%u] `%s' baserate %u Bips, amplitude %u Bps\n", | ||
328 | dest->me->no, | ||
329 | GNUNET_i2s (&dest->me->id), | ||
330 | dest->dest->no, | ||
331 | GNUNET_i2s (&dest->dest->id), | ||
332 | base_rate, | ||
333 | max_rate); | ||
334 | break; | ||
335 | |||
336 | case GNUNET_ATS_TEST_TG_RANDOM: | ||
337 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
338 | "Setting up random traffic generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bps\n", | ||
339 | dest->me->no, | ||
340 | GNUNET_i2s (&dest->me->id), | ||
341 | dest->dest->no, | ||
342 | GNUNET_i2s (&dest->dest->id), | ||
343 | base_rate, | ||
344 | max_rate); | ||
345 | break; | ||
346 | |||
347 | default: | ||
348 | break; | ||
349 | } | ||
350 | |||
351 | dest->tg = tg; | ||
352 | tg->send_task | ||
353 | = GNUNET_SCHEDULER_add_now (&comm_schedule_send, | ||
354 | dest); | ||
355 | return tg; | ||
356 | } | ||
357 | |||
358 | |||
359 | void | ||
360 | GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg) | ||
361 | { | ||
362 | GNUNET_CONTAINER_DLL_remove (tg_head, | ||
363 | tg_tail, | ||
364 | tg); | ||
365 | tg->dest->tg = NULL; | ||
366 | if (NULL != tg->send_task) | ||
367 | { | ||
368 | GNUNET_SCHEDULER_cancel (tg->send_task); | ||
369 | tg->send_task = NULL; | ||
370 | } | ||
371 | GNUNET_free (tg); | ||
372 | } | ||
373 | |||
374 | |||
375 | /** | ||
376 | * Stop all traffic generators | ||
377 | */ | ||
378 | void | ||
379 | GNUNET_ATS_TEST_generate_traffic_stop_all () | ||
380 | { | ||
381 | struct TrafficGenerator *cur; | ||
382 | struct TrafficGenerator *next; | ||
383 | |||
384 | next = tg_head; | ||
385 | for (cur = next; NULL != cur; cur = next) | ||
386 | { | ||
387 | next = cur->next; | ||
388 | GNUNET_ATS_TEST_generate_traffic_stop (cur); | ||
389 | } | ||
390 | } | ||
391 | |||
392 | |||
393 | /* end of file ats-testing-traffic.c */ | ||