2 This file is part of GNUnet.
3 (C) 2009 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.
22 * @file src/transport/gnunet-transport.c
23 * @brief Tool to help configure, measure and control the transport subsystem.
24 * @author Christian Grothoff
26 * This utility can be used to test if a transport mechanism for
27 * GNUnet is properly configured.
31 #include "gnunet_program_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_transport_service.h"
37 static struct GNUNET_TRANSPORT_Handle *handle;
39 static int benchmark_send;
41 static int benchmark_receive;
45 static unsigned long long traffic_received;
47 static unsigned long long traffic_sent;
49 static struct GNUNET_TIME_Absolute start_time;
51 static struct GNUNET_TRANSPORT_TransmitHandle *th;
53 static struct GNUNET_PeerIdentity pid;
55 static GNUNET_SCHEDULER_TaskIdentifier end;
59 * Shutdown, print statistics.
62 do_disconnect (void *cls,
63 const struct GNUNET_SCHEDULER_TaskContext *tc)
65 struct GNUNET_TIME_Relative duration;
69 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
72 GNUNET_TRANSPORT_disconnect (handle);
73 if (benchmark_receive)
75 duration = GNUNET_TIME_absolute_get_duration (start_time);
77 "Received %llu bytes/s\n",
78 traffic_received / (1+duration.rel_value));
82 duration = GNUNET_TIME_absolute_get_duration (start_time);
84 "Transmitted %llu bytes/s\n",
85 traffic_sent / (1+duration.rel_value));
91 * Function called to notify a client about the socket
92 * begin ready to queue more data. "buf" will be
93 * NULL and "size" zero if the socket was closed for
94 * writing in the meantime.
97 * @param size number of bytes available in buf
98 * @param buf where the callee should write the message
99 * @return number of bytes written to buf
102 transmit_data (void *cls, size_t size,
105 struct GNUNET_MessageHeader *m = buf;
107 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
108 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
109 m->size = ntohs (size);
110 m->type = ntohs (GNUNET_MESSAGE_TYPE_DUMMY);
111 memset (&m[1], 52, size - sizeof (struct GNUNET_MessageHeader));
112 traffic_sent += size;
113 th = GNUNET_TRANSPORT_notify_transmit_ready (handle,
117 GNUNET_TIME_UNIT_FOREVER_REL,
118 &transmit_data, NULL);
124 * Function called to notify transport users that another
125 * peer connected to us.
128 * @param peer the peer that connected
129 * @param ats performance data
130 * @param ats_count number of entries in ats (excluding 0-termination)
133 notify_connect (void *cls,
134 const struct GNUNET_PeerIdentity
137 GNUNET_ATS_Information
138 * ats, uint32_t ats_count)
140 if (0 != memcmp (&pid,
142 sizeof (struct GNUNET_PeerIdentity)))
147 start_time = GNUNET_TIME_absolute_get ();
148 th = GNUNET_TRANSPORT_notify_transmit_ready (handle,
152 GNUNET_TIME_UNIT_FOREVER_REL,
153 &transmit_data, NULL);
157 /* all done, terminate instantly */
158 GNUNET_SCHEDULER_cancel (end);
159 end = GNUNET_SCHEDULER_add_now (&do_disconnect,
166 * Function called to notify transport users that another
167 * peer disconnected from us.
170 * @param peer the peer that disconnected
173 notify_disconnect (void *cls,
175 GNUNET_PeerIdentity * peer)
177 if ( (0 == memcmp (&pid,
179 sizeof (struct GNUNET_PeerIdentity))) &&
182 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
184 GNUNET_SCHEDULER_cancel (end);
185 end = GNUNET_SCHEDULER_add_now (&do_disconnect,
192 * Function called by the transport for each received message.
195 * @param peer (claimed) identity of the other peer
196 * @param message the message
197 * @param ats performance data
198 * @param ats_count number of entries in ats
201 notify_receive (void *cls,
203 GNUNET_PeerIdentity * peer,
205 GNUNET_MessageHeader *
208 GNUNET_ATS_Information
209 * ats, uint32_t ats_count)
211 if (! benchmark_receive)
213 if (traffic_received == 0)
214 start_time = GNUNET_TIME_absolute_get ();
215 traffic_received += ntohs (message->size);
220 * Main function that will be run by the scheduler.
223 * @param args remaining command-line arguments
224 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
225 * @param cfg configuration
228 run (void *cls, char *const *args, const char *cfgfile,
229 const struct GNUNET_CONFIGURATION_Handle *cfg)
231 if (benchmark_send && (NULL == cpid))
233 fprintf (stderr, _("Option `%s' makes no sense without option `%s'.\n"),
240 handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL,
245 GNUNET_CRYPTO_hash_from_string (cpid, &pid.hashPubKey))
248 _("Failed to parse peer identity `%s'\n"),
250 GNUNET_TRANSPORT_disconnect (handle);
253 GNUNET_TRANSPORT_try_connect (handle, &pid);
254 end = GNUNET_SCHEDULER_add_delayed (benchmark_send
255 ? GNUNET_TIME_UNIT_FOREVER_REL
256 : GNUNET_TIME_UNIT_SECONDS,
264 main (int argc, char *const *argv)
266 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
267 {'b', "benchmark", NULL,
268 gettext_noop ("measure how fast we are receiving data (until CTRL-C)"),
269 0, &GNUNET_GETOPT_set_one, &benchmark_receive},
270 {'C', "connect", "PEER",
271 gettext_noop ("try to connect to the given peer"),
272 1, &GNUNET_GETOPT_set_string, &cpid},
274 gettext_noop ("send data for benchmarking to the other peer (until CTRL-C)"),
275 0, &GNUNET_GETOPT_set_one, &benchmark_send},
276 GNUNET_GETOPT_OPTION_END
279 GNUNET_PROGRAM_run (argc, argv, "gnunet-transport",
280 gettext_noop ("Direct access to transport service."),
281 options, &run, NULL)) ? ret : 1;
285 /* end of gnunet-transport.c */