|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- /*
- * This file is part of GNUnet
- * Copyright (C) 2013 GNUnet e.V.
- *
- * GNUnet is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License,
- * or (at your option) any later version.
- *
- * GNUnet is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-
- /**
- * @file multicast/test_multicast_2peers.c
- * @brief Tests for the Multicast API with two peers doing the ping
- * pong test.
- * @author xrs
- */
-
- #include <inttypes.h>
-
- #include "platform.h"
- #include "gnunet_crypto_lib.h"
- #include "gnunet_common.h"
- #include "gnunet_util_lib.h"
- #include "gnunet_testbed_service.h"
- #include "gnunet_multicast_service.h"
-
- #define NUM_PEERS 2
-
- static struct GNUNET_TESTBED_Operation *op0;
- static struct GNUNET_TESTBED_Operation *op1;
- static struct GNUNET_TESTBED_Operation *pi_op0;
- static struct GNUNET_TESTBED_Operation *pi_op1;
-
- static struct GNUNET_TESTBED_Peer **peers;
- const struct GNUNET_PeerIdentity *peer_id[2];
-
- static struct GNUNET_SCHEDULER_Task *timeout_tid;
-
- static struct GNUNET_MULTICAST_Origin *origin;
- static struct GNUNET_MULTICAST_Member *member;
-
- struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
- struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
-
- struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
- struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
-
- /**
- * Global result for testcase.
- */
- static int result;
-
-
- /**
- * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
- * Cleans up.
- */
- static void
- shutdown_task (void *cls)
- {
- if (NULL != op0)
- {
- GNUNET_TESTBED_operation_done (op0);
- op0 = NULL;
- }
- if (NULL != op1)
- {
- GNUNET_TESTBED_operation_done (op1);
- op1 = NULL;
- }
- if (NULL != pi_op0)
- {
- GNUNET_TESTBED_operation_done (pi_op0);
- pi_op0 = NULL;
- }
- if (NULL != pi_op1)
- {
- GNUNET_TESTBED_operation_done (pi_op1);
- pi_op1 = NULL;
- }
- if (NULL != timeout_tid)
- {
- GNUNET_SCHEDULER_cancel (timeout_tid);
- timeout_tid = NULL;
- }
- }
-
-
- static void
- timeout_task (void *cls)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Timeout!\n");
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- }
-
-
- static void
- member_join_request (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
- const struct GNUNET_MessageHeader *join_msg,
- struct GNUNET_MULTICAST_JoinHandle *jh)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member sent a join request.\n");
-
- }
-
-
- static int
- notify (void *cls,
- size_t *data_size,
- void *data)
- {
-
- char text[] = "ping";
- *data_size = strlen(text)+1;
- GNUNET_memcpy(data, text, *data_size);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member sents message to origin: %s\n", text);
-
- return GNUNET_YES;
- }
-
-
- static void
- member_join_decision (void *cls,
- int is_admitted,
- const struct GNUNET_PeerIdentity *peer,
- uint16_t relay_count,
- const struct GNUNET_PeerIdentity *relays,
- const struct GNUNET_MessageHeader *join_msg)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member received a decision from origin: %s\n",
- (GNUNET_YES == is_admitted)
- ? "accepted"
- : "rejected");
-
- if (GNUNET_YES == is_admitted)
- {
- struct GNUNET_MULTICAST_MemberTransmitHandle *req;
-
- // FIXME: move to MQ-style API!
- req = GNUNET_MULTICAST_member_to_origin (member,
- 0,
- ¬ify,
- NULL);
- }
- }
-
-
- static void
- member_message (void *cls,
- const struct GNUNET_MULTICAST_MessageHeader *msg)
- {
- if (0 != strncmp ("pong", (char *)&msg[1], 4))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "member did not receive pong\n");
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "member receives: %s\n", (char *)&msg[1]);
-
- // Testcase ends here.
- result = GNUNET_YES;
- GNUNET_SCHEDULER_shutdown ();
- }
-
-
- static void
- origin_join_request (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
- const struct GNUNET_MessageHeader *join_msg,
- struct GNUNET_MULTICAST_JoinHandle *jh)
- {
- struct GNUNET_MessageHeader *join_resp;
-
- uint8_t data_size = ntohs (join_msg->size);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "origin got a join request...\n");
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "origin receives: '%s'\n", (char *)&join_msg[1]);
-
- const char data[] = "Come in!";
- data_size = strlen (data) + 1;
- join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
- join_resp->size = htons (sizeof (join_resp) + data_size);
- join_resp->type = htons (123);
- GNUNET_memcpy (&join_resp[1], data, data_size);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "origin sends: '%s'\n", data);
-
- GNUNET_MULTICAST_join_decision (jh,
- GNUNET_YES,
- 0,
- NULL,
- join_resp);
- GNUNET_free (join_resp);
- result = GNUNET_OK;
- }
-
-
- int
- origin_notify (void *cls,
- size_t *data_size,
- void *data)
- {
- char text[] = "pong";
-
- *data_size = strlen(text)+1;
- GNUNET_memcpy (data,
- text,
- *data_size);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin sends (to all): %s\n", text);
-
- return GNUNET_YES;
- }
-
-
- static void
- origin_request (void *cls,
- const struct GNUNET_MULTICAST_RequestHeader *req)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin receives: %s\n", (char *)&req[1]);
-
- if (0 != strncmp ("ping", (char *)&req[1], 4))
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "origin didn't reveice a correct request");
-
- GNUNET_MULTICAST_origin_to_all (origin,
- 0,
- 0,
- origin_notify,
- NULL);
- }
-
-
- static void
- origin_message (void *cls,
- const struct GNUNET_MULTICAST_MessageHeader *msg)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin message msg\n");
- }
-
-
- static void
- service_connect1 (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- void *ca_result,
- const char *emsg)
- {
- member = ca_result;
-
- if (NULL == member)
- {
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n");
- }
- }
-
-
- static void
- multicast_da1 (void *cls,
- void * op_result)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member parting from multicast group\n");
-
- GNUNET_MULTICAST_member_part (member, NULL, NULL);
- }
-
-
- static void *
- multicast_ca1 (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
- {
- struct GNUNET_MessageHeader *join_msg;
- void *ret;
-
- // Get members keys
- member_key = GNUNET_CRYPTO_ecdsa_key_create ();
- GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
-
- char data[] = "Hi, can I enter?";
- uint8_t data_size = strlen (data) + 1;
- join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
- join_msg->size = htons (sizeof (join_msg) + data_size);
- join_msg->type = htons (123);
- GNUNET_memcpy (&join_msg[1], data, data_size);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Members tries to join multicast group\n");
-
- ret = GNUNET_MULTICAST_member_join (cfg,
- &group_pub_key,
- member_key,
- peer_id[0],
- 0,
- NULL,
- join_msg, /* join message */
- member_join_request,
- member_join_decision,
- NULL, /* no test for member_replay_frag */
- NULL, /* no test for member_replay_msg */
- member_message,
- NULL);
- GNUNET_free (join_msg);
- return ret;
- }
-
-
- static void
- peer_information_cb (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- const struct GNUNET_TESTBED_PeerInformation *pinfo,
- const char *emsg)
- {
- int i = (int) (long) cls;
-
- if (NULL == pinfo)
- {
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- }
-
- peer_id[i] = pinfo->result.id;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Got peer information of %s (%s)\n", (0==i)?"origin":"member" ,GNUNET_i2s(pinfo->result.id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Create member peer\n");
-
- if (0 == i)
- {
- /* connect to multicast service of member */
- op1 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
- peers[1], /* The peer whose service to connect to */
- "multicast", /* The name of the service */
- service_connect1, /* callback to call after a handle to service
- is opened */
- NULL, /* closure for the above callback */
- multicast_ca1, /* callback to call with peer's configuration;
- this should open the needed service connection */
- multicast_da1, /* callback to be called when closing the
- opened service connection */
- NULL); /* closure for the above two callbacks */
- }
- }
-
-
- /**
- * Test logic of peer "0" being origin starts here.
- *
- * @param cls closure, for the example: NULL
- * @param op should be equal to "dht_op"
- * @param ca_result result of the connect operation, the
- * connection to the DHT service
- * @param emsg error message, if testbed somehow failed to
- * connect to the DHT.
- */
- static void
- service_connect0 (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- void *ca_result,
- const char *emsg)
- {
- origin = ca_result;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Connected to multicast service of origin\n");
-
- // Get GNUnet identity of origin
- pi_op0 = GNUNET_TESTBED_peer_get_information (peers[0],
- GNUNET_TESTBED_PIT_IDENTITY,
- peer_information_cb,
- (void *) 0);
- // Get GNUnet identity of member
- pi_op1 = GNUNET_TESTBED_peer_get_information (peers[1],
- GNUNET_TESTBED_PIT_IDENTITY,
- peer_information_cb,
- (void *) 1);
-
- /* Connection to service successful. Here we'd usually do something with
- * the service. */
- result = GNUNET_OK;
- //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
- }
-
-
-
- /**
- * Function run when service multicast has started and is providing us
- * with a configuration file.
- */
- static void *
- multicast_ca0 (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
- {
- group_key = GNUNET_CRYPTO_eddsa_key_create ();
- GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
-
- return GNUNET_MULTICAST_origin_start (cfg,
- group_key,
- 0,
- origin_join_request,
- NULL, /* no test for origin_replay_frag */
- NULL, /* no test for origin_replay_msg */
- origin_request,
- origin_message,
- NULL);
- }
-
- static void
- multicast_da0 (void *cls,
- void *op_result)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Origin closes multicast group\n");
-
- GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
- }
-
-
- /**
- * Main function inovked from TESTBED once all of the
- * peers are up and running. This one then connects
- * just to the multicast service of peer 0 and 1.
- * Peer 0 is going to be origin.
- * Peer 1 is going to be one member.
- * Origin will start a multicast group and the member will try to join it.
- * After that we execute some multicast test.
- *
- * @param cls closure
- * @param h the run handle
- * @param peers started peers for the test
- * @param num_peers size of the 'peers' array
- * @param links_succeeded number of links between peers that were created
- * @param links_failed number of links testbed was unable to establish
- */
- static void
- testbed_master (void *cls,
- struct GNUNET_TESTBED_RunHandle *h,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **p,
- unsigned int links_succeeded,
- unsigned int links_failed)
- {
- /* Testbed is ready with peers running and connected in a pre-defined overlay
- topology (FIXME) */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Connected to testbed_master()\n");
-
- peers = p;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Create origin peer\n");
- op0 = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
- peers[0], /* The peer whose service to connect to */
- "multicast", /* The name of the service */
- service_connect0, /* callback to call after a handle to service
- is opened */
- NULL, /* closure for the above callback */
- multicast_ca0, /* callback to call with peer's configuration;
- this should open the needed service connection */
- multicast_da0, /* callback to be called when closing the
- opened service connection */
- NULL); /* closure for the above two callbacks */
-
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
-
- /* Schedule the shutdown task with a delay of a few Seconds */
- timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 50),
- &timeout_task, NULL);
- }
-
-
- int
- main (int argc, char *argv[])
- {
- int ret;
-
- result = GNUNET_SYSERR;
- ret = GNUNET_TESTBED_test_run
- ("test-multicast-2peers", /* test case name */
- "test_multicast.conf", /* template configuration */
- NUM_PEERS, /* number of peers to start */
- 0LL, /* Event mask - set to 0 for no event notifications */
- NULL, /* Controller event callback */
- NULL, /* Closure for controller event callback */
- testbed_master, /* continuation callback to be called when testbed setup is complete */
- NULL); /* Closure for the test_master callback */
- if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
- return 1;
- return 0;
- }
-
-
- /* end of test_multicast_2peers.c */
|