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 it
6 * under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License,
8 * or (at your 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 * Affero General Public License for more details.
17 * @file multicast/test_multicast_2peers.c
18 * @brief Tests for the Multicast API with two peers doing the ping
26 #include "gnunet_crypto_lib.h"
27 #include "gnunet_common.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testbed_service.h"
30 #include "gnunet_multicast_service.h"
34 static struct GNUNET_TESTBED_Operation *op0;
35 static struct GNUNET_TESTBED_Operation *op1;
36 static struct GNUNET_TESTBED_Operation *pi_op0;
37 static struct GNUNET_TESTBED_Operation *pi_op1;
39 static struct GNUNET_TESTBED_Peer **peers;
40 const struct GNUNET_PeerIdentity *peer_id[2];
42 static struct GNUNET_SCHEDULER_Task *timeout_tid;
44 static struct GNUNET_MULTICAST_Origin *origin;
45 static struct GNUNET_MULTICAST_Member *member;
47 struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
48 struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
50 struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
51 struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
54 * Global result for testcase.
60 * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
64 shutdown_task (void *cls)
68 GNUNET_TESTBED_operation_done (op0);
73 GNUNET_TESTBED_operation_done (op1);
78 GNUNET_TESTBED_operation_done (pi_op0);
83 GNUNET_TESTBED_operation_done (pi_op1);
86 if (NULL != timeout_tid)
88 GNUNET_SCHEDULER_cancel (timeout_tid);
95 timeout_task (void *cls)
97 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
99 result = GNUNET_SYSERR;
100 GNUNET_SCHEDULER_shutdown ();
105 member_join_request (void *cls,
106 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
107 const struct GNUNET_MessageHeader *join_msg,
108 struct GNUNET_MULTICAST_JoinHandle *jh)
110 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
111 "Member sent a join request.\n");
122 char text[] = "ping";
123 *data_size = strlen(text)+1;
124 GNUNET_memcpy(data, text, *data_size);
126 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
127 "Member sents message to origin: %s\n", text);
134 member_join_decision (void *cls,
136 const struct GNUNET_PeerIdentity *peer,
137 uint16_t relay_count,
138 const struct GNUNET_PeerIdentity *relays,
139 const struct GNUNET_MessageHeader *join_msg)
141 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
142 "Member received a decision from origin: %s\n",
143 (GNUNET_YES == is_admitted)
147 if (GNUNET_YES == is_admitted)
149 struct GNUNET_MULTICAST_MemberTransmitHandle *req;
151 // FIXME: move to MQ-style API!
152 req = GNUNET_MULTICAST_member_to_origin (member,
161 member_message (void *cls,
162 const struct GNUNET_MULTICAST_MessageHeader *msg)
164 if (0 != strncmp ("pong", (char *)&msg[1], 4))
166 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "member did not receive pong\n");
167 result = GNUNET_SYSERR;
168 GNUNET_SCHEDULER_shutdown ();
171 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
172 "member receives: %s\n", (char *)&msg[1]);
174 // Testcase ends here.
176 GNUNET_SCHEDULER_shutdown ();
181 origin_join_request (void *cls,
182 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
183 const struct GNUNET_MessageHeader *join_msg,
184 struct GNUNET_MULTICAST_JoinHandle *jh)
186 struct GNUNET_MessageHeader *join_resp;
188 uint8_t data_size = ntohs (join_msg->size);
190 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
191 "origin got a join request...\n");
192 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
193 "origin receives: '%s'\n", (char *)&join_msg[1]);
195 const char data[] = "Come in!";
196 data_size = strlen (data) + 1;
197 join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
198 join_resp->size = htons (sizeof (join_resp) + data_size);
199 join_resp->type = htons (123);
200 GNUNET_memcpy (&join_resp[1], data, data_size);
202 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
203 "origin sends: '%s'\n", data);
205 GNUNET_MULTICAST_join_decision (jh,
210 GNUNET_free (join_resp);
216 origin_notify (void *cls,
220 char text[] = "pong";
222 *data_size = strlen(text)+1;
227 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin sends (to all): %s\n", text);
234 origin_request (void *cls,
235 const struct GNUNET_MULTICAST_RequestHeader *req)
237 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin receives: %s\n", (char *)&req[1]);
239 if (0 != strncmp ("ping", (char *)&req[1], 4))
240 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "origin didn't reveice a correct request");
242 GNUNET_MULTICAST_origin_to_all (origin,
251 origin_message (void *cls,
252 const struct GNUNET_MULTICAST_MessageHeader *msg)
254 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin message msg\n");
259 service_connect1 (void *cls,
260 struct GNUNET_TESTBED_Operation *op,
268 result = GNUNET_SYSERR;
269 GNUNET_SCHEDULER_shutdown ();
273 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n");
279 multicast_da1 (void *cls,
282 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
283 "Member parting from multicast group\n");
285 GNUNET_MULTICAST_member_part (member, NULL, NULL);
290 multicast_ca1 (void *cls,
291 const struct GNUNET_CONFIGURATION_Handle *cfg)
293 struct GNUNET_MessageHeader *join_msg;
297 member_key = GNUNET_CRYPTO_ecdsa_key_create ();
298 GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
300 char data[] = "Hi, can I enter?";
301 uint8_t data_size = strlen (data) + 1;
302 join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
303 join_msg->size = htons (sizeof (join_msg) + data_size);
304 join_msg->type = htons (123);
305 GNUNET_memcpy (&join_msg[1], data, data_size);
307 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
308 "Members tries to join multicast group\n");
310 ret = GNUNET_MULTICAST_member_join (cfg,
316 join_msg, /* join message */
318 member_join_decision,
319 NULL, /* no test for member_replay_frag */
320 NULL, /* no test for member_replay_msg */
323 GNUNET_free (join_msg);
329 peer_information_cb (void *cls,
330 struct GNUNET_TESTBED_Operation *op,
331 const struct GNUNET_TESTBED_PeerInformation *pinfo,
334 int i = (int) (long) cls;
338 result = GNUNET_SYSERR;
339 GNUNET_SCHEDULER_shutdown ();
342 peer_id[i] = pinfo->result.id;
344 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
345 "Got peer information of %s (%s)\n", (0==i)?"origin":"member" ,GNUNET_i2s(pinfo->result.id));
347 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
348 "Create member peer\n");
352 /* connect to multicast service of member */
353 op1 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
354 peers[1], /* The peer whose service to connect to */
355 "multicast", /* The name of the service */
356 service_connect1, /* callback to call after a handle to service
358 NULL, /* closure for the above callback */
359 multicast_ca1, /* callback to call with peer's configuration;
360 this should open the needed service connection */
361 multicast_da1, /* callback to be called when closing the
362 opened service connection */
363 NULL); /* closure for the above two callbacks */
369 * Test logic of peer "0" being origin starts here.
371 * @param cls closure, for the example: NULL
372 * @param op should be equal to "dht_op"
373 * @param ca_result result of the connect operation, the
374 * connection to the DHT service
375 * @param emsg error message, if testbed somehow failed to
376 * connect to the DHT.
379 service_connect0 (void *cls,
380 struct GNUNET_TESTBED_Operation *op,
386 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
387 "Connected to multicast service of origin\n");
389 // Get GNUnet identity of origin
390 pi_op0 = GNUNET_TESTBED_peer_get_information (peers[0],
391 GNUNET_TESTBED_PIT_IDENTITY,
394 // Get GNUnet identity of member
395 pi_op1 = GNUNET_TESTBED_peer_get_information (peers[1],
396 GNUNET_TESTBED_PIT_IDENTITY,
400 /* Connection to service successful. Here we'd usually do something with
403 //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
409 * Function run when service multicast has started and is providing us
410 * with a configuration file.
413 multicast_ca0 (void *cls,
414 const struct GNUNET_CONFIGURATION_Handle *cfg)
416 group_key = GNUNET_CRYPTO_eddsa_key_create ();
417 GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
419 return GNUNET_MULTICAST_origin_start (cfg,
423 NULL, /* no test for origin_replay_frag */
424 NULL, /* no test for origin_replay_msg */
431 multicast_da0 (void *cls,
434 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
435 "Origin closes multicast group\n");
437 GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
442 * Main function inovked from TESTBED once all of the
443 * peers are up and running. This one then connects
444 * just to the multicast service of peer 0 and 1.
445 * Peer 0 is going to be origin.
446 * Peer 1 is going to be one member.
447 * Origin will start a multicast group and the member will try to join it.
448 * After that we execute some multicast test.
451 * @param h the run handle
452 * @param peers started peers for the test
453 * @param num_peers size of the 'peers' array
454 * @param links_succeeded number of links between peers that were created
455 * @param links_failed number of links testbed was unable to establish
458 testbed_master (void *cls,
459 struct GNUNET_TESTBED_RunHandle *h,
460 unsigned int num_peers,
461 struct GNUNET_TESTBED_Peer **p,
462 unsigned int links_succeeded,
463 unsigned int links_failed)
465 /* Testbed is ready with peers running and connected in a pre-defined overlay
467 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
468 "Connected to testbed_master()\n");
472 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
473 "Create origin peer\n");
474 op0 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
475 peers[0], /* The peer whose service to connect to */
476 "multicast", /* The name of the service */
477 service_connect0, /* callback to call after a handle to service
479 NULL, /* closure for the above callback */
480 multicast_ca0, /* callback to call with peer's configuration;
481 this should open the needed service connection */
482 multicast_da0, /* callback to be called when closing the
483 opened service connection */
484 NULL); /* closure for the above two callbacks */
486 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
488 /* Schedule the shutdown task with a delay of a few Seconds */
489 timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 50),
490 &timeout_task, NULL);
495 main (int argc, char *argv[])
499 result = GNUNET_SYSERR;
500 ret = GNUNET_TESTBED_test_run
501 ("test-multicast-2peers", /* test case name */
502 "test_multicast.conf", /* template configuration */
503 NUM_PEERS, /* number of peers to start */
504 0LL, /* Event mask - set to 0 for no event notifications */
505 NULL, /* Controller event callback */
506 NULL, /* Closure for controller event callback */
507 testbed_master, /* continuation callback to be called when testbed setup is complete */
508 NULL); /* Closure for the test_master callback */
509 if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
515 /* end of test_multicast_2peers.c */