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_2peers.c
23 * @brief Tests for the Multicast API with two peers doing the ping
31 #include "gnunet_crypto_lib.h"
32 #include "gnunet_common.h"
33 #include "gnunet_util_lib.h"
34 #include "gnunet_testbed_service.h"
35 #include "gnunet_multicast_service.h"
39 static struct GNUNET_TESTBED_Operation *op0;
40 static struct GNUNET_TESTBED_Operation *op1;
41 static struct GNUNET_TESTBED_Operation *pi_op0;
42 static struct GNUNET_TESTBED_Operation *pi_op1;
44 static struct GNUNET_TESTBED_Peer **peers;
45 const struct GNUNET_PeerIdentity *peer_id[2];
47 static struct GNUNET_SCHEDULER_Task *timeout_tid;
49 static struct GNUNET_MULTICAST_Origin *origin;
50 static struct GNUNET_MULTICAST_Member *member;
52 struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
53 struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
55 struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
56 struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
59 * Global result for testcase.
65 * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
69 shutdown_task (void *cls)
73 GNUNET_TESTBED_operation_done (op0);
78 GNUNET_TESTBED_operation_done (op1);
83 GNUNET_TESTBED_operation_done (pi_op0);
88 GNUNET_TESTBED_operation_done (pi_op1);
91 if (NULL != timeout_tid)
93 GNUNET_SCHEDULER_cancel (timeout_tid);
100 timeout_task (void *cls)
102 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
104 result = GNUNET_SYSERR;
105 GNUNET_SCHEDULER_shutdown ();
110 member_join_request (void *cls,
111 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
112 const struct GNUNET_MessageHeader *join_msg,
113 struct GNUNET_MULTICAST_JoinHandle *jh)
115 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
116 "Member sent a join request.\n");
120 int notify (void *cls,
125 char text[] = "ping";
126 *data_size = strlen(text)+1;
127 GNUNET_memcpy(data, text, *data_size);
129 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
130 "Member sents message to origin: %s\n", text);
137 member_join_decision (void *cls,
139 const struct GNUNET_PeerIdentity *peer,
140 uint16_t relay_count,
141 const struct GNUNET_PeerIdentity *relays,
142 const struct GNUNET_MessageHeader *join_msg)
144 struct GNUNET_MULTICAST_MemberTransmitHandle *req;
146 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
147 "Member received a decision from origin: %s\n", (GNUNET_YES == is_admitted)?"accepted":"rejected");
149 if (GNUNET_YES == is_admitted)
151 req = GNUNET_MULTICAST_member_to_origin (member,
159 member_message (void *cls,
160 const struct GNUNET_MULTICAST_MessageHeader *msg)
162 if (0 != strncmp ("pong", (char *)&msg[1], 4))
164 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "member did not receive pong\n");
165 result = GNUNET_SYSERR;
166 GNUNET_SCHEDULER_shutdown ();
169 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
170 "member receives: %s\n", (char *)&msg[1]);
172 // Testcase ends here.
174 GNUNET_SCHEDULER_shutdown ();
178 origin_join_request (void *cls,
179 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
180 const struct GNUNET_MessageHeader *join_msg,
181 struct GNUNET_MULTICAST_JoinHandle *jh)
183 struct GNUNET_MessageHeader *join_resp;
185 uint8_t data_size = ntohs (join_msg->size);
187 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
188 "origin got a join request...\n");
189 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
190 "origin receives: '%s'\n", (char *)&join_msg[1]);
192 char data[] = "Come in!";
193 data_size = strlen (data) + 1;
194 join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
195 join_resp->size = htons (sizeof (join_resp) + data_size);
196 join_resp->type = htons (123);
197 GNUNET_memcpy (&join_resp[1], data, data_size);
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
200 "origin sends: '%s'\n", data);
202 GNUNET_MULTICAST_join_decision (jh,
212 origin_notify (void *cls,
216 char text[] = "pong";
217 *data_size = strlen(text)+1;
218 memcpy(data, text, *data_size);
220 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin sends (to all): %s\n", text);
227 origin_request (void *cls,
228 const struct GNUNET_MULTICAST_RequestHeader *req)
230 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin receives: %s\n", (char *)&req[1]);
232 if (0 != strncmp ("ping", (char *)&req[1], 4))
233 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "origin didn't reveice a correct request");
235 GNUNET_MULTICAST_origin_to_all (origin,
243 origin_message (void *cls,
244 const struct GNUNET_MULTICAST_MessageHeader *msg)
246 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin message msg\n");
251 service_connect1 (void *cls,
252 struct GNUNET_TESTBED_Operation *op,
260 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n");
264 result = GNUNET_SYSERR;
265 GNUNET_SCHEDULER_shutdown ();
270 multicast_da1 (void *cls,
273 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
274 "Member parting from multicast group\n");
276 GNUNET_MULTICAST_member_part (member, NULL, NULL);
281 multicast_ca1 (void *cls,
282 const struct GNUNET_CONFIGURATION_Handle *cfg)
284 struct GNUNET_MessageHeader *join_msg;
287 member_key = GNUNET_CRYPTO_ecdsa_key_create ();
288 GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
290 char data[] = "Hi, can I enter?";
291 uint8_t data_size = strlen (data) + 1;
292 join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
293 join_msg->size = htons (sizeof (join_msg) + data_size);
294 join_msg->type = htons (123);
295 GNUNET_memcpy (&join_msg[1], data, data_size);
297 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
298 "Members tries to join multicast group\n");
300 return GNUNET_MULTICAST_member_join (cfg,
306 join_msg, /* join message */
308 member_join_decision,
309 NULL, /* no test for member_replay_frag */
310 NULL, /* no test for member_replay_msg */
317 peer_information_cb (void *cls,
318 struct GNUNET_TESTBED_Operation *op,
319 const struct GNUNET_TESTBED_PeerInformation *pinfo,
322 int i = (int) (long) cls;
326 result = GNUNET_SYSERR;
327 GNUNET_SCHEDULER_shutdown ();
330 peer_id[i] = pinfo->result.id;
332 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
333 "Got peer information of %s (%s)\n", (0==i)?"origin":"member" ,GNUNET_i2s(pinfo->result.id));
335 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
336 "Create member peer\n");
340 /* connect to multicast service of member */
341 op1 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
342 peers[1], /* The peer whose service to connect to */
343 "multicast", /* The name of the service */
344 service_connect1, /* callback to call after a handle to service
346 NULL, /* closure for the above callback */
347 multicast_ca1, /* callback to call with peer's configuration;
348 this should open the needed service connection */
349 multicast_da1, /* callback to be called when closing the
350 opened service connection */
351 NULL); /* closure for the above two callbacks */
356 * Test logic of peer "0" being origin starts here.
358 * @param cls closure, for the example: NULL
359 * @param op should be equal to "dht_op"
360 * @param ca_result result of the connect operation, the
361 * connection to the DHT service
362 * @param emsg error message, if testbed somehow failed to
363 * connect to the DHT.
366 service_connect0 (void *cls,
367 struct GNUNET_TESTBED_Operation *op,
373 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
374 "Connected to multicast service of origin\n");
376 // Get GNUnet identity of origin
377 pi_op0 = GNUNET_TESTBED_peer_get_information (peers[0],
378 GNUNET_TESTBED_PIT_IDENTITY,
381 // Get GNUnet identity of member
382 pi_op1 = GNUNET_TESTBED_peer_get_information (peers[1],
383 GNUNET_TESTBED_PIT_IDENTITY,
387 /* Connection to service successful. Here we'd usually do something with
390 //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
396 * Function run when service multicast has started and is providing us
397 * with a configuration file.
400 multicast_ca0 (void *cls,
401 const struct GNUNET_CONFIGURATION_Handle *cfg)
403 group_key = GNUNET_CRYPTO_eddsa_key_create ();
404 GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
406 return GNUNET_MULTICAST_origin_start (cfg,
410 NULL, /* no test for origin_replay_frag */
411 NULL, /* no test for origin_replay_msg */
418 multicast_da0 (void *cls,
421 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
422 "Origin closes multicast group\n");
424 GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
429 * Main function inovked from TESTBED once all of the
430 * peers are up and running. This one then connects
431 * just to the multicast service of peer 0 and 1.
432 * Peer 0 is going to be origin.
433 * Peer 1 is going to be one member.
434 * Origin will start a multicast group and the member will try to join it.
435 * After that we execute some multicast test.
438 * @param h the run handle
439 * @param peers started peers for the test
440 * @param num_peers size of the 'peers' array
441 * @param links_succeeded number of links between peers that were created
442 * @param links_failed number of links testbed was unable to establish
445 testbed_master (void *cls,
446 struct GNUNET_TESTBED_RunHandle *h,
447 unsigned int num_peers,
448 struct GNUNET_TESTBED_Peer **p,
449 unsigned int links_succeeded,
450 unsigned int links_failed)
452 /* Testbed is ready with peers running and connected in a pre-defined overlay
454 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
455 "Connected to testbed_master()\n");
459 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
460 "Create origin peer\n");
461 op0 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
462 peers[0], /* The peer whose service to connect to */
463 "multicast", /* The name of the service */
464 service_connect0, /* callback to call after a handle to service
466 NULL, /* closure for the above callback */
467 multicast_ca0, /* callback to call with peer's configuration;
468 this should open the needed service connection */
469 multicast_da0, /* callback to be called when closing the
470 opened service connection */
471 NULL); /* closure for the above two callbacks */
473 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
475 /* Schedule the shutdown task with a delay of a few Seconds */
476 timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 50),
477 &timeout_task, NULL);
482 main (int argc, char *argv[])
486 result = GNUNET_SYSERR;
487 ret = GNUNET_TESTBED_test_run
488 ("test-multicast-multipeer", /* test case name */
489 "test_multicast.conf", /* template configuration */
490 NUM_PEERS, /* number of peers to start */
491 0LL, /* Event mask - set to 0 for no event notifications */
492 NULL, /* Controller event callback */
493 NULL, /* Closure for controller event callback */
494 testbed_master, /* continuation callback to be called when testbed setup is complete */
495 NULL); /* Closure for the test_master callback */
496 if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
501 /* end of test_multicast_multipeer.c */