2 This file is part of GNUnet.
3 (C) 2010-2013 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, 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 delay.rel_value_us = 0;
42 case GNUNET_ATS_TEST_TG_CONSTANT:
43 if (UINT32_MAX == tg->rate)
44 delay.rel_value_us = 0;
45 else if (tg->rate <= TEST_MESSAGE_SIZE)
46 delay.rel_value_us = (GNUNET_TIME_UNIT_SECONDS.rel_value_us);
48 delay.rel_value_us = (GNUNET_TIME_UNIT_SECONDS.rel_value_us / (tg->rate / TEST_MESSAGE_SIZE));
50 case GNUNET_ATS_TEST_TG_LINEAR:
53 case GNUNET_ATS_TEST_TG_RANDOM:
56 case GNUNET_ATS_TEST_TG_SINUS:
67 send_ping_ready_cb (void *cls, size_t size, void *buf)
69 struct BenchmarkPartner *p = cls;
70 static char msgbuf[TEST_MESSAGE_SIZE];
71 struct GNUNET_MessageHeader *msg;
78 if (size < TEST_MESSAGE_SIZE)
84 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Master [%u]: Sending PING to [%u]\n",
85 p->me->no, p->dest->no);
104 msg = (struct GNUNET_MessageHeader *) &msgbuf;
105 memset (&msgbuf, 'a', TEST_MESSAGE_SIZE);
106 msg->type = htons (TEST_MESSAGE_TYPE_PING);
107 msg->size = htons (TEST_MESSAGE_SIZE);
108 memcpy (buf, msg, TEST_MESSAGE_SIZE);
111 p->bytes_sent += TEST_MESSAGE_SIZE;
112 p->me->total_messages_sent++;
113 p->me->total_bytes_sent += TEST_MESSAGE_SIZE;
118 return TEST_MESSAGE_SIZE;
120 p->tg->next_ping_transmission = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(),
123 return TEST_MESSAGE_SIZE;
128 comm_schedule_send (void *cls,
129 const struct GNUNET_SCHEDULER_TaskContext* tc)
131 struct BenchmarkPartner *p = cls;
133 p->tg->send_task = GNUNET_SCHEDULER_NO_TASK;
135 p->last_message_sent = GNUNET_TIME_absolute_get();
136 if (GNUNET_YES == top->test_core)
138 p->cth = GNUNET_CORE_notify_transmit_ready (
139 p->me->ch, GNUNET_NO,
140 GNUNET_CORE_PRIO_BEST_EFFORT,
141 GNUNET_TIME_UNIT_MINUTES, &p->dest->id,
142 TEST_MESSAGE_SIZE, &send_ping_ready_cb, p);
146 p->tth = GNUNET_TRANSPORT_notify_transmit_ready (
147 p->me->th, &p->dest->id, TEST_MESSAGE_SIZE, 0,GNUNET_TIME_UNIT_MINUTES,
148 &send_ping_ready_cb, p);
154 comm_send_pong_ready (void *cls, size_t size, void *buf)
156 static char msgbuf[TEST_MESSAGE_SIZE];
157 struct BenchmarkPartner *p = cls;
158 struct GNUNET_MessageHeader *msg;
160 if (GNUNET_YES == top->test_core)
166 p->bytes_sent += TEST_MESSAGE_SIZE;
167 p->me->total_messages_sent++;
168 p->me->total_bytes_sent += TEST_MESSAGE_SIZE;
170 msg = (struct GNUNET_MessageHeader *) &msgbuf;
171 memset (&msgbuf, 'a', TEST_MESSAGE_SIZE);
172 msg->type = htons (TEST_MESSAGE_TYPE_PONG);
173 msg->size = htons (TEST_MESSAGE_SIZE);
174 memcpy (buf, msg, TEST_MESSAGE_SIZE);
176 return TEST_MESSAGE_SIZE;
181 GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p)
183 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
184 "Slave [%u]: Received PING from [%u], sending PONG\n", p->me->no,
187 p->messages_received++;
188 p->bytes_received += TEST_MESSAGE_SIZE;
189 p->me->total_messages_received++;
190 p->me->total_bytes_received += TEST_MESSAGE_SIZE;
192 if (GNUNET_YES == top->test_core)
194 GNUNET_assert (NULL == p->cth);
197 = GNUNET_CORE_notify_transmit_ready (p->me->ch, GNUNET_NO,
198 GNUNET_CORE_PRIO_BEST_EFFORT,
199 GNUNET_TIME_UNIT_MINUTES,
200 &p->dest->id, TEST_MESSAGE_SIZE,
201 &comm_send_pong_ready, p);
205 GNUNET_assert (NULL == p->tth);
206 p->tth = GNUNET_TRANSPORT_notify_transmit_ready (p->me->th, &p->dest->id,
207 TEST_MESSAGE_SIZE, 0, GNUNET_TIME_UNIT_MINUTES, &comm_send_pong_ready,
213 GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p)
215 struct GNUNET_TIME_Relative left;
216 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
217 "Master [%u]: Received PONG from [%u], next message\n", p->me->no,
220 p->messages_received++;
221 p->bytes_received += TEST_MESSAGE_SIZE;
222 p->me->total_messages_received++;
223 p->me->total_bytes_received += TEST_MESSAGE_SIZE;
224 p->total_app_rtt += GNUNET_TIME_absolute_get_difference(p->last_message_sent,
225 GNUNET_TIME_absolute_get()).rel_value_us;
227 /* Schedule next send event */
228 left = GNUNET_TIME_absolute_get_remaining(p->tg->next_ping_transmission);
229 if (UINT32_MAX == p->tg->rate)
231 p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
233 else if (0 == left.rel_value_us)
235 p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
239 p->tg->send_task = GNUNET_SCHEDULER_add_delayed (left,
240 &comm_schedule_send, p);
246 * Generate between the source master and the partner and send traffic with a
250 struct TrafficGenerator *
251 GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
252 struct BenchmarkPartner *dest,
253 enum TrafficGeneratorType type,
255 struct GNUNET_TIME_Relative duration)
257 struct TrafficGenerator * tg;
260 if (NULL != dest->tg)
266 tg = GNUNET_new (struct TrafficGenerator);
267 GNUNET_CONTAINER_DLL_insert (tg_head, tg_tail, tg);
272 tg->next_ping_transmission = GNUNET_TIME_UNIT_FOREVER_ABS;
274 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
275 "Setting up traffic generator master[%u] `%s' and slave [%u] `%s' max %u Bips\n",
276 dest->me->no, GNUNET_i2s (&dest->me->id),
277 dest->dest->no, GNUNET_i2s (&dest->dest->id),
280 if ( ((GNUNET_YES == top->test_core) && (NULL != dest->cth)) ||
281 ((GNUNET_NO == top->test_core) && (NULL != dest->tth)) )
284 GNUNET_CONTAINER_DLL_remove (tg_head, tg_tail, tg);
290 tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, dest);
295 GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg)
298 GNUNET_CONTAINER_DLL_remove (tg_head, tg_tail, tg);
301 if (GNUNET_SCHEDULER_NO_TASK != tg->send_task)
303 GNUNET_SCHEDULER_cancel (tg->send_task);
304 tg->send_task = GNUNET_SCHEDULER_NO_TASK;
308 if (NULL != tg->dest->cth)
310 GNUNET_CORE_notify_transmit_ready_cancel (tg->dest->cth);
311 tg->dest->cth = NULL;
316 if (NULL != tg->dest->tth)
318 GNUNET_TRANSPORT_notify_transmit_ready_cancel (tg->dest->tth);
319 tg->dest->tth = NULL;
326 * Stop all traffic generators
329 GNUNET_ATS_TEST_generate_traffic_stop_all ()
331 struct TrafficGenerator *cur;
332 struct TrafficGenerator *next;
334 for (cur = next; NULL != cur; cur = next)
337 GNUNET_ATS_TEST_generate_traffic_stop(cur);
341 /* end of file ats-testing-traffic.c */