#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;
+#define NUM_PEERS 3
- struct GNUNET_TESTBED_Operation *op;
- struct GNUNET_TESTBED_Operation *pi_op;
+struct multicast_peer
+{
+ int peer; /* peer number */
++ struct GNUNET_TESTBED_Operation *op; /* not yet in use */
++ struct GNUNET_TESTBED_Operation *pi_op; /* not yet in use */
++ uint8_t test_ok;
+};
+
+static void service_connect (void *cls,
+ struct GNUNET_TESTBED_Operation *op,
+ void *ca_result,
+ const char *emsg);
+
+static struct multicast_peer **mc_peers;
static struct GNUNET_TESTBED_Peer **peers;
-const struct GNUNET_PeerIdentity *peer_id[2];
+
-static struct GNUNET_SCHEDULER_Task *timeout_tid;
++// FIXME: refactor
+static struct GNUNET_TESTBED_Operation *op[NUM_PEERS];
+static struct GNUNET_TESTBED_Operation *pi_op[NUM_PEERS];
+static const struct GNUNET_PeerIdentity *peer_id[NUM_PEERS];
static struct GNUNET_MULTICAST_Origin *origin;
- static struct GNUNET_MULTICAST_Member *member[NUM_PEERS];
-static struct GNUNET_MULTICAST_Member *member;
++static struct GNUNET_MULTICAST_Member *member[NUM_PEERS]; /* first element always empty */
-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;
+static struct GNUNET_SCHEDULER_Task *timeout_tid;
+static struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
+static struct GNUNET_CRYPTO_EddsaPublicKey *group_pub_key;
-enum
-{
- TEST_INIT = 0,
- TEST_ORIGIN_START = 1,
- TEST_MEMBER_JOIN = 2,
-} test;
+static struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key[NUM_PEERS];
+static struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key[NUM_PEERS];
/**
*/
static int result;
--
/**
* Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
* Cleans up.
}
-int notify (void *cls,
- size_t *data_size,
- void *data)
++
+static int
+notify (void *cls,
+ size_t *data_size,
+ void *data)
{
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
char text[] = "ping";
*data_size = strlen(text)+1;
}
}
++
static void
member_replay_frag ()
{
"member replay frag...\n");
}
++
static void
member_replay_msg ()
{
"member replay msg...\n");
}
++
static void
--member_message ()
++member_message (void *cls,
++ const struct GNUNET_MULTICAST_MessageHeader *msg)
{
++ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
++
++ if (0 != strncmp ("pong", (char *)&msg[1], 4))
++ {
++ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
++ "peer #%i did not receive pong\n",
++ mc_peer->peer);
++
++ result = GNUNET_SYSERR;
++ GNUNET_SCHEDULER_shutdown ();
++ }
++
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-- "member message...\n");
++ "peer #%i receives: %s\n",
++ mc_peer->peer,
++ (char *)&msg[1]);
++
++ mc_peer->test_ok = GNUNET_OK;
++
++ // FIXME: ugly test function
++ /*
++ for (int i=1; i<NUM_PEERS; i++)
++ if (!mc_peers[i]->test_ok)
++ return;
-- // FIXME: not finished here
result = GNUNET_YES;
-- GNUNET_SCHEDULER_shutdown ();
++ GNUNET_SCHEDULER_shutdown();
++ */
}
++
static void
origin_join_request (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
result = GNUNET_OK;
}
++
static void
origin_replay_frag (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay fraq msg\n");
}
++
static void
origin_replay_msg (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
0,
0,
origin_notify,
- NULL);
+ cls);
}
++
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)
+multicast_da (void *cls,
+ void *op_result)
{
- member = ca_result;
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
- if (NULL != member)
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n");
- else
- result = GNUNET_SYSERR;
-}
+ if (0 == mc_peer->peer)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Origin closes multicast group\n");
-static void
-multicast_da1 (void *cls,
- void * op_result)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member parting from multicast group\n");
+ GNUNET_MULTICAST_origin_stop (origin, NULL, cls);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "peer #%u parting from multicast group\n", mc_peer->peer);
- GNUNET_MULTICAST_member_part (member, NULL, NULL);
+ GNUNET_MULTICAST_member_part (member[mc_peer->peer], NULL, cls);
+ }
}
static void *
-multicast_ca1 (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+multicast_ca (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
struct GNUNET_MessageHeader *join_msg;
-
- // Get members keys
- member_key = GNUNET_CRYPTO_ecdsa_key_create ();
- GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
+ char data[64];
- 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");
-
- return 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,
- member_replay_frag,
- member_replay_msg,
- member_message,
- NULL);
+ if (0 == mc_peer->peer)
+ {
+ group_pub_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey);
+ 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,
+ origin_replay_frag,
+ origin_replay_msg,
+ origin_request,
+ origin_message,
+ cls);
+ }
+ else
+ {
+ // Get members keys
+ member_pub_key[mc_peer->peer] = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
+ member_key[mc_peer->peer] = GNUNET_CRYPTO_ecdsa_key_create ();
+ GNUNET_CRYPTO_ecdsa_key_get_public (member_key[mc_peer->peer], member_pub_key[mc_peer->peer]);
+
+ sprintf(data, "Hi, I am peer #%u. Can I enter?", mc_peer->peer);
+ 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,
+ "Peer #%u tries to join multicast group\n", mc_peer->peer);
+
+ return GNUNET_MULTICAST_member_join (cfg,
+ group_pub_key,
+ member_key[mc_peer->peer],
+ peer_id[0],
+ 0,
+ NULL,
+ join_msg, /* join message */
+ member_join_request,
+ member_join_decision,
+ member_replay_frag,
+ member_replay_msg,
+ member_message,
+ cls);
+ }
}
+
static void
peer_information_cb (void *cls,
- struct GNUNET_TESTBED_Operation *op,
+ struct GNUNET_TESTBED_Operation *operation,
const struct GNUNET_TESTBED_PeerInformation *pinfo,
const char *emsg)
{
}
}
-/**
- * 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)
+service_connect (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 */
-}
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+ if (NULL == ca_result)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Connection adapter not created for peer #%u\n", mc_peer->peer);
+ result = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_shutdown();
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Connected to multicast service of peer #%u\n", mc_peer->peer);
-/**
- * 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,
- origin_replay_frag,
- origin_replay_msg,
- origin_request,
- origin_message,
- NULL);
-}
+ if (0 == mc_peer->peer)
+ {
+ origin = ca_result;
-static void
-multicast_da0 (void *cls,
- void *op_result)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Origin closes multicast group\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Connected to multicast service of origin\n");
- GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
+ // Get GNUnet identity of members
+ for (int i = 0; i<NUM_PEERS; i++)
+ {
+ pi_op[i] = GNUNET_TESTBED_peer_get_information (peers[i],
+ GNUNET_TESTBED_PIT_IDENTITY,
+ peer_information_cb,
+ mc_peers[i]);
+ }
+ }
+ else
+ {
- member[mc_peer->peer-1] = ca_result;
++ member[mc_peer->peer] = ca_result;
+ }
}
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 */
+
+ mc_peers = GNUNET_new_array (NUM_PEERS, struct multicast_peer*);
+
+ // Create test contexts for members
+ for (int i = 0; i<NUM_PEERS; i++)
+ {
+ mc_peers[i] = GNUNET_new (struct multicast_peer);
+ mc_peers[i]->peer = i;
++ mc_peers[i]->test_ok = GNUNET_NO;
+ }
+
+ op[0] = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
+ peers[0], /* The peer whose service to connect to */
+ "multicast", /* The name of the service */
+ service_connect, /* callback to call after a handle to service
+ is opened */
+ mc_peers[0], /* closure for the above callback */
+ multicast_ca, /* callback to call with peer's configuration;
+ this should open the needed service connection */
+ multicast_da, /* callback to be called when closing the
+ opened service connection */
+ mc_peers[0]); /* 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, 60),
- timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 48),
++ timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 80),
&timeout_task, NULL);
}