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_Operation *pi_op0;
41 static struct GNUNET_TESTBED_Operation *pi_op1;
43 static struct GNUNET_TESTBED_Peer **peers;
44 const struct GNUNET_PeerIdentity *peer_id[2];
46 static struct GNUNET_SCHEDULER_Task *timeout_tid;
48 static struct GNUNET_MULTICAST_Origin *origin;
49 static struct GNUNET_MULTICAST_Member *member;
51 struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
52 struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
54 struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
55 struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
61 TEST_ORIGIN_START = 1,
67 * Global result for testcase.
73 * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
77 shutdown_task (void *cls)
81 GNUNET_TESTBED_operation_done (op0);
86 GNUNET_TESTBED_operation_done (op1);
91 GNUNET_TESTBED_operation_done (pi_op0);
96 GNUNET_TESTBED_operation_done (pi_op1);
99 if (NULL != timeout_tid)
101 GNUNET_SCHEDULER_cancel (timeout_tid);
108 timeout_task (void *cls)
111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
113 result = GNUNET_SYSERR;
114 GNUNET_SCHEDULER_shutdown ();
119 member_join_request (void *cls,
120 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
121 const struct GNUNET_MessageHeader *join_msg,
122 struct GNUNET_MULTICAST_JoinHandle *jh)
124 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
125 "Member sent a join request.\n");
131 member_join_decision (void *cls,
133 const struct GNUNET_PeerIdentity *peer,
134 uint16_t relay_count,
135 const struct GNUNET_PeerIdentity *relays,
136 const struct GNUNET_MessageHeader *join_msg)
138 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
139 "Member received a decision from origin: %s\n", (GNUNET_YES == is_admitted)?"accepted":"rejected");
142 GNUNET_SCHEDULER_shutdown ();
146 member_replay_frag ()
148 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
149 "member replay frag...\n");
155 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
156 "member replay msg...\n");
162 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
163 "member message...\n");
167 origin_join_request (void *cls,
168 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
169 const struct GNUNET_MessageHeader *join_msg,
170 struct GNUNET_MULTICAST_JoinHandle *jh)
172 struct GNUNET_MessageHeader *join_resp;
174 uint8_t data_size = ntohs (join_msg->size);
176 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
177 "Dizzy: Mh, got a join request...\n");
178 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
179 "'%s'\n", (char *)&join_msg[1]);
180 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
181 "Dizzy: Oh, it's Bird! Let's get him in.\n");
183 char data[] = "Hi, Bird. Come in!";
184 data_size = strlen (data) + 1;
185 join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
186 join_resp->size = htons (sizeof (join_resp) + data_size);
187 join_resp->type = htons (123);
188 GNUNET_memcpy (&join_resp[1], data, data_size);
190 GNUNET_MULTICAST_join_decision (jh,
200 origin_replay_frag (void *cls,
201 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
202 uint64_t fragment_id,
204 struct GNUNET_MULTICAST_ReplayHandle *rh)
206 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay fraq msg\n");
210 origin_replay_msg (void *cls,
211 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
213 uint64_t fragment_offset,
215 struct GNUNET_MULTICAST_ReplayHandle *rh)
218 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay msg\n");
222 origin_request (void *cls,
223 const struct GNUNET_MULTICAST_RequestHeader *req)
225 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin request msg\n");
230 origin_message (void *cls,
231 const struct GNUNET_MULTICAST_MessageHeader *msg)
233 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin message msg\n");
238 service_connect1 (void *cls,
239 struct GNUNET_TESTBED_Operation *op,
246 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n");
248 result = GNUNET_SYSERR;
252 multicast_da1 (void *cls,
255 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
256 "Member parting from multicast group\n");
258 GNUNET_MULTICAST_member_part (member, NULL, NULL);
263 multicast_ca1 (void *cls,
264 const struct GNUNET_CONFIGURATION_Handle *cfg)
266 struct GNUNET_MessageHeader *join_msg;
269 member_key = GNUNET_CRYPTO_ecdsa_key_create ();
270 GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
272 char data[] = "Whut's up, Dizzy!";
273 uint8_t data_size = strlen (data) + 1;
274 join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
275 join_msg->size = htons (sizeof (join_msg) + data_size);
276 join_msg->type = htons (123);
277 GNUNET_memcpy (&join_msg[1], data, data_size);
279 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
280 "Members tries to join multicast group\n");
282 return GNUNET_MULTICAST_member_join (cfg,
288 join_msg, /* join message */
290 member_join_decision,
299 peer_information_cb (void *cls,
300 struct GNUNET_TESTBED_Operation *op,
301 const struct GNUNET_TESTBED_PeerInformation *pinfo,
304 int i = (int) (long) cls;
307 result = GNUNET_SYSERR;
308 GNUNET_SCHEDULER_shutdown ();
311 peer_id[i] = pinfo->result.id;
313 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
314 "Got peer information of %s (%s)\n", (0==i)?"origin":"member" ,GNUNET_i2s(pinfo->result.id));
316 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
317 "Create member peer\n");
320 /* connect to multicast service of member */
321 op1 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
322 peers[1], /* The peer whose service to connect to */
323 "multicast", /* The name of the service */
324 service_connect1, /* callback to call after a handle to service
326 NULL, /* closure for the above callback */
327 multicast_ca1, /* callback to call with peer's configuration;
328 this should open the needed service connection */
329 multicast_da1, /* callback to be called when closing the
330 opened service connection */
331 NULL); /* closure for the above two callbacks */
336 * Test logic of peer "0" being origin starts here.
338 * @param cls closure, for the example: NULL
339 * @param op should be equal to "dht_op"
340 * @param ca_result result of the connect operation, the
341 * connection to the DHT service
342 * @param emsg error message, if testbed somehow failed to
343 * connect to the DHT.
346 service_connect0 (void *cls,
347 struct GNUNET_TESTBED_Operation *op,
353 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
354 "Connected to multicast service of origin\n");
356 // Get GNUnet identity of origin
357 pi_op0 = GNUNET_TESTBED_peer_get_information (peers[0],
358 GNUNET_TESTBED_PIT_IDENTITY,
361 // Get GNUnet identity of member
362 pi_op1 = GNUNET_TESTBED_peer_get_information (peers[1],
363 GNUNET_TESTBED_PIT_IDENTITY,
367 /* Connection to service successful. Here we'd usually do something with
370 //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
376 * Function run when service multicast has started and is providing us
377 * with a configuration file.
380 multicast_ca0 (void *cls,
381 const struct GNUNET_CONFIGURATION_Handle *cfg)
383 group_key = GNUNET_CRYPTO_eddsa_key_create ();
384 GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
386 return GNUNET_MULTICAST_origin_start (cfg,
398 multicast_da0 (void *cls,
401 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
402 "Origin closes multicast group\n");
404 GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
409 * Main function inovked from TESTBED once all of the
410 * peers are up and running. This one then connects
411 * just to the multicast service of peer 0 and 1.
412 * Peer 0 is going to be origin.
413 * Peer 1 is going to be one member.
414 * Origin will start a multicast group and the member will try to join it.
415 * After that we execute some multicast test.
418 * @param h the run handle
419 * @param peers started peers for the test
420 * @param num_peers size of the 'peers' array
421 * @param links_succeeded number of links between peers that were created
422 * @param links_failed number of links testbed was unable to establish
425 testbed_master (void *cls,
426 struct GNUNET_TESTBED_RunHandle *h,
427 unsigned int num_peers,
428 struct GNUNET_TESTBED_Peer **p,
429 unsigned int links_succeeded,
430 unsigned int links_failed)
432 /* Testbed is ready with peers running and connected in a pre-defined overlay
434 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
435 "Connected to testbed_master()\n");
439 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
440 "Create origin peer\n");
441 op0 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
442 peers[0], /* The peer whose service to connect to */
443 "multicast", /* The name of the service */
444 service_connect0, /* callback to call after a handle to service
446 NULL, /* closure for the above callback */
447 multicast_ca0, /* callback to call with peer's configuration;
448 this should open the needed service connection */
449 multicast_da0, /* callback to be called when closing the
450 opened service connection */
451 NULL); /* closure for the above two callbacks */
453 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
455 /* Schedule the shutdown task with a delay of a few Seconds */
456 timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 40),
457 &timeout_task, NULL);
462 main (int argc, char *argv[])
466 result = GNUNET_SYSERR;
467 ret = GNUNET_TESTBED_test_run
468 ("test-multicast-multipeer", /* test case name */
469 "test_multicast.conf", /* template configuration */
470 NUM_PEERS, /* number of peers to start */
471 0LL, /* Event mask - set to 0 for no event notifications */
472 NULL, /* Controller event callback */
473 NULL, /* Closure for controller event callback */
474 testbed_master, /* continuation callback to be called when testbed setup is complete */
475 NULL); /* Closure for the test_master callback */
476 if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
481 /* end of test_multicast_multipeer.c */