#include "gnunet_testbed_service.h"
#include "gnunet_multicast_service.h"
-#define NUM_PEERS 2
+#define NUM_PEERS 3
-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;
+struct multicast_peer
+{
+ int peer; /* peer number */
+ struct GNUNET_TESTBED_Operation *op;
+ struct GNUNET_TESTBED_Operation *pi_op;
+};
-static struct GNUNET_TESTBED_Peer **peers;
-const struct GNUNET_PeerIdentity *peer_id[2];
+static void service_connect (void *cls,
+ struct GNUNET_TESTBED_Operation *op,
+ void *ca_result,
+ const char *emsg);
-static struct GNUNET_SCHEDULER_Task *timeout_tid;
+static struct multicast_peer **mc_peers;
+static struct GNUNET_TESTBED_Peer **peers;
+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;
-
-struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
-struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
+static struct GNUNET_MULTICAST_Member *member[NUM_PEERS];
-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 void
shutdown_task (void *cls)
{
- if (NULL != op0)
+ if (NULL != mc_peers)
{
- GNUNET_TESTBED_operation_done (op0);
- op0 = NULL;
- }
- if (NULL != op1)
- {
- GNUNET_TESTBED_operation_done (op1);
- op1 = NULL;
+ for (int i=0; i < NUM_PEERS; i++)
+ {
+ GNUNET_free (mc_peers[i]);
+ mc_peers[i] = NULL;
+ }
+ GNUNET_free (mc_peers);
}
- if (NULL != pi_op0)
+
+ for (int i=0;i<NUM_PEERS;i++)
{
- GNUNET_TESTBED_operation_done (pi_op0);
- pi_op0 = NULL;
+ if (NULL != op[i])
+ {
+ GNUNET_TESTBED_operation_done(op[i]);
+ op[i] = NULL;
+ }
+ if (NULL != pi_op[i])
+ {
+ GNUNET_TESTBED_operation_done (pi_op[i]);
+ pi_op[i] = NULL;
+ }
}
- if (NULL != pi_op1)
+
+ if (NULL != timeout_tid)
{
- GNUNET_TESTBED_operation_done (pi_op1);
- pi_op1 = NULL;
+ GNUNET_SCHEDULER_cancel (timeout_tid);
+ timeout_tid = NULL;
}
- if (NULL != timeout_tid)
- {
- GNUNET_SCHEDULER_cancel (timeout_tid);
- timeout_tid = NULL;
- }
}
const struct GNUNET_MessageHeader *join_msg,
struct GNUNET_MULTICAST_JoinHandle *jh)
{
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member sent a join request.\n");
+ "Peer #%u sent a join request.\n", mc_peer->peer);
}
-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;
GNUNET_memcpy(data, text, *data_size);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member sents message to origin: %s\n", text);
+ "Peer #%u sents message to origin: %s\n", mc_peer->peer, text);
return GNUNET_YES;
}
const struct GNUNET_PeerIdentity *relays,
const struct GNUNET_MessageHeader *join_msg)
{
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
struct GNUNET_MULTICAST_MemberTransmitHandle *req;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Member received a decision from origin: %s\n", (GNUNET_YES == is_admitted)?"accepted":"rejected");
+ "Peer #%u received a decision from origin: %s\n", mc_peer->peer, (GNUNET_YES == is_admitted)?"accepted":"rejected");
if (GNUNET_YES == is_admitted)
{
- req = GNUNET_MULTICAST_member_to_origin (member,
+ req = GNUNET_MULTICAST_member_to_origin (member[mc_peer->peer],
0,
notify,
- NULL);
+ cls);
}
}
}
-int
+static int
origin_notify (void *cls,
size_t *data_size,
void *data)
0,
0,
origin_notify,
- NULL);
+ cls);
}
static void
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_EddsaPublicKey);
+ 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)
{
- int i = (int) (long) cls;
+ struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
if (NULL == pinfo) {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got no peer information\n");
result = GNUNET_SYSERR;
GNUNET_SCHEDULER_shutdown ();
}
- peer_id[i] = pinfo->result.id;
+ peer_id[mc_peer->peer] = 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));
+ "Got peer information of %s (%s)\n", (0==mc_peer->peer)?"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 */
+ "Create peer #%u\n", mc_peer->peer);
+
+ if (0 != mc_peer->peer)
+ {
+ /* connect to multicast service of members */
+ op[mc_peer->peer] = GNUNET_TESTBED_service_connect (NULL, /* Closure for operation */
+ peers[mc_peer->peer], /* 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 */
+ cls, /* 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 */
+ cls); /* 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)
+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;
+ }
}
+
/**
* Main function inovked from TESTBED once all of the
* peers are up and running. This one then connects
{
/* 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");
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;
+ }
+
+ 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 */