2 * This file is part of GNUnet
3 * Copyright (C) 2013 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.
22 * @file multicast/test_multicast_multipeers.c
23 * @brief Tests for the Multicast API with multiple peers.
30 #include "gnunet_crypto_lib.h"
31 #include "gnunet_common.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_testbed_service.h"
34 #include "gnunet_multicast_service.h"
38 static struct GNUNET_TESTBED_Operation *op0;
39 static struct GNUNET_TESTBED_Operation *op1;
40 static struct GNUNET_TESTBED_Peer **peers;
42 static struct GNUNET_SCHEDULER_Task *timeout_tid;
44 static struct GNUNET_MULTICAST_Origin *origin;
46 struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
47 struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
49 struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
50 struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
56 TEST_ORIGIN_START = 1,
62 * Global result for testcase.
68 * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
72 shutdown_task (void *cls)
76 GNUNET_TESTBED_operation_done (op0);
81 GNUNET_TESTBED_operation_done (op1);
84 if (NULL != timeout_tid)
86 GNUNET_SCHEDULER_cancel (timeout_tid);
93 timeout_task (void *cls)
96 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
98 result = GNUNET_SYSERR;
99 GNUNET_SCHEDULER_shutdown ();
104 struct GNUNET_TESTBED_Operation *op,
105 const struct GNUNET_TESTBED_PeerInformation *pinfo,
111 member_join_request (void *cls,
112 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
113 const struct GNUNET_MessageHeader *join_msg,
114 struct GNUNET_MULTICAST_JoinHandle *jh)
116 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
117 "Member sent a join request.");
123 member_join_decision (void *cls,
125 const struct GNUNET_PeerIdentity *peer,
126 uint16_t relay_count,
127 const struct GNUNET_PeerIdentity *relays,
128 const struct GNUNET_MessageHeader *join_msg)
130 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
131 "Member received a decision from origin: ...");
136 member_replay_frag ()
138 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
139 "member replay frag...");
145 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
146 "member replay msg...");
152 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
153 "member message...");
157 origin_join_request (void *cls,
158 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
159 const struct GNUNET_MessageHeader *join_msg,
160 struct GNUNET_MULTICAST_JoinHandle *jh)
162 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
163 "yey, got a join request. Let's see who it is.");
169 origin_replay_frag (void *cls,
170 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
171 uint64_t fragment_id,
173 struct GNUNET_MULTICAST_ReplayHandle *rh)
179 origin_replay_msg (void *cls,
180 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
182 uint64_t fragment_offset,
184 struct GNUNET_MULTICAST_ReplayHandle *rh)
187 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay msg\n");
191 origin_request (void *cls,
192 const struct GNUNET_MULTICAST_RequestHeader *req)
194 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin request msg\n");
199 origin_message (void *cls,
200 const struct GNUNET_MULTICAST_MessageHeader *msg)
206 service_connect1 (void *cls,
207 struct GNUNET_TESTBED_Operation *op,
211 struct GNUNET_MULTICAST_Member *member = ca_result;
214 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "connected to multicast service of member\n");
216 result = GNUNET_SYSERR;
220 multicast_da1 (void *cls,
223 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
224 "disconnecting from multicast service of member\n");
229 multicast_ca1 (void *cls,
230 const struct GNUNET_CONFIGURATION_Handle *cfg)
232 struct GNUNET_MessageHeader *join_msg;
233 const struct GNUNET_PeerIdentity *peer_id_origin;
234 struct GNUNET_HashCode pub_hash;
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "connecting to multicast service of member...\n");
239 member_key = GNUNET_CRYPTO_ecdsa_key_create ();
240 GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
242 // Get GNUnet identity of origin
243 peer_id_origin = GNUNET_TESTBED_peer_get_information (peers[0],
244 GNUNET_TESTBED_PIT_IDENTITY,
248 GNUNET_assert(NULL != peer_id_origin);
250 GNUNET_CRYPTO_hash (&peer_id_origin, sizeof (peer_id_origin), &pub_hash);
251 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
252 "member: id of origin is %s\n",
253 GNUNET_h2s (&pub_hash));
255 char data[] = "Hello Mr. Smith!";
256 uint8_t data_size = strlen (data) + 1;
257 join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
258 join_msg->size = htons (sizeof (join_msg) + data_size);
259 join_msg->type = htons (123);
260 GNUNET_memcpy (&join_msg[1], data, data_size);
262 return GNUNET_MULTICAST_member_join (cfg,
268 join_msg, /* join message */
270 member_join_decision,
279 * Test logic of peer "0" being origin starts here.
281 * @param cls closure, for the example: NULL
282 * @param op should be equal to "dht_op"
283 * @param ca_result result of the connect operation, the
284 * connection to the DHT service
285 * @param emsg error message, if testbed somehow failed to
286 * connect to the DHT.
289 service_connect0 (void *cls,
290 struct GNUNET_TESTBED_Operation *op,
294 struct GNUNET_MULTICAST_Origin *origin = ca_result;
296 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
297 "connected to multicast service of origin\n");
299 /* Connection to service successful. Here we'd usually do something with
302 //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
308 * Function run when service multicast has started and is providing us
309 * with a configuration file.
312 multicast_ca0 (void *cls,
313 const struct GNUNET_CONFIGURATION_Handle *cfg)
315 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
316 "connecting to multicast service of origin...\n");
318 group_key = GNUNET_CRYPTO_eddsa_key_create ();
319 GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
321 return GNUNET_MULTICAST_origin_start (cfg,
333 multicast_da0 (void *cls,
336 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
337 "disconnecting from multicast service of origin\n");
342 * Main function inovked from TESTBED once all of the
343 * peers are up and running. This one then connects
344 * just to the multicast service of peer 0 and 1.
345 * Peer 0 is going to be origin.
346 * Peer 1 is going to be one member.
347 * Origin will start a multicast group and the member will try to join it.
348 * After that we execute some multicast test.
351 * @param h the run handle
352 * @param peers started peers for the test
353 * @param num_peers size of the 'peers' array
354 * @param links_succeeded number of links between peers that were created
355 * @param links_failed number of links testbed was unable to establish
358 testbed_master (void *cls,
359 struct GNUNET_TESTBED_RunHandle *h,
360 unsigned int num_peers,
361 struct GNUNET_TESTBED_Peer **p,
362 unsigned int links_succeeded,
363 unsigned int links_failed)
365 /* Testbed is ready with peers running and connected in a pre-defined overlay
368 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
369 "connected to testbed_master()\n");
373 /* connect to a peers service */
374 op0 = GNUNET_TESTBED_service_connect
375 (NULL, /* Closure for operation */
376 peers[0], /* The peer whose service to connect to */
377 "multicast", /* The name of the service */
378 service_connect0, /* callback to call after a handle to service
380 NULL, /* closure for the above callback */
381 multicast_ca0, /* callback to call with peer's configuration;
382 this should open the needed service connection */
383 multicast_da0, /* callback to be called when closing the
384 opened service connection */
385 NULL); /* closure for the above two callbacks */
387 op1 = GNUNET_TESTBED_service_connect
388 (NULL, /* Closure for operation */
389 peers[1], /* The peer whose service to connect to */
390 "multicast", /* The name of the service */
391 service_connect1, /* callback to call after a handle to service
393 NULL, /* closure for the above callback */
394 multicast_ca1, /* callback to call with peer's configuration;
395 this should open the needed service connection */
396 multicast_da1, /* callback to be called when closing the
397 opened service connection */
398 NULL); /* closure for the above two callbacks */
400 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
402 /* Schedule the shutdown task with a delay of a few 1econds */
403 timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3),
404 &timeout_task, NULL);
409 main (int argc, char *argv[])
413 result = GNUNET_SYSERR;
414 ret = GNUNET_TESTBED_test_run
415 ("test-multicast-multipeer", /* test case name */
416 "test_multicast.conf", /* template configuration */
417 NUM_PEERS, /* number of peers to start */
418 0LL, /* Event mask - set to 0 for no event notifications */
419 NULL, /* Controller event callback */
420 NULL, /* Closure for controller event callback */
421 testbed_master, /* continuation callback to be called when testbed setup is complete */
422 NULL); /* Closure for the test_master callback */
423 if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
428 /* end of test_multicast_multipeer.c */