-service sharing message handling
authorSree Harsha Totakura <totakura@in.tum.de>
Sun, 24 Jun 2012 16:52:10 +0000 (16:52 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Sun, 24 Jun 2012 16:52:10 +0000 (16:52 +0000)
src/testbed/gnunet-service-testbed.c
src/testbed/testbed.h
src/testbed/testbed_api.c

index c87b2e21f7e01d361953cd34e1da0c035783fe4f..77448216247a50e2557d1e3499ff33db3e10fa3d 100644 (file)
@@ -90,6 +90,27 @@ struct MessageQueue
 };
 
 
+/**
+ * The structure for identifying a shared service
+ */
+struct SharedService
+{
+  /**
+   * The name of the shared service
+   */
+  char *name;
+
+  /**
+   * Number of shared peers per instance of the shared service
+   */
+  uint32_t num_shared;
+
+  /**
+   * Number of peers currently sharing the service
+   */
+  uint32_t num_sharing;
+};
+
 
 /**
  * Wrapped stdin.
@@ -131,6 +152,11 @@ static struct MessageQueue *mq_tail;
  */
 struct GNUNET_SERVER_TransmitHandle *transmit_handle;
 
+/**
+ * The hashmap of shared services
+ */
+struct GNUNET_CONTAINER_MultiHashMap *ss_map;
+
 
 /**
  * Function called to notify a client about the connection begin ready to queue
@@ -231,6 +257,24 @@ host_list_add (struct GNUNET_TESTBED_Host *host)
 }
 
 
+/**
+ * Routes message to a host given its host_id
+ *
+ * @param host_id the id of the destination host
+ * @param msg the message to be routed
+ */
+static void
+route_message (uint32_t host_id, const struct GNUNET_MessageHeader *msg)
+{
+  GNUNET_break (0);
+}
+
+
+/**
+ * 
+ */
+
+
 /**
  * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
  *
@@ -275,9 +319,9 @@ handle_init (void *cls,
  * @param message the actual message
  */
 static void 
-handle_addhost (void *cls,
-                struct GNUNET_SERVER_Client *client,
-                const struct GNUNET_MessageHeader *message)
+handle_add_host (void *cls,
+                 struct GNUNET_SERVER_Client *client,
+                 const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_TESTBED_Host *host;
   const struct GNUNET_TESTBED_AddHostMessage *msg;
@@ -335,6 +379,83 @@ handle_addhost (void *cls,
 }
 
 
+/**
+ * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages
+ *
+ * @param cls NULL
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void 
+handle_configure_shared_service (void *cls,
+                                 struct GNUNET_SERVER_Client *client,
+                                 const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_TESTBED_ConfigureSharedServiceMessage *msg;
+  struct SharedService *ss;
+  char *service_name;
+  struct GNUNET_HashCode hash;
+  uint16_t msg_size;
+  uint16_t service_name_size;
+    
+  msg = (struct GNUNET_TESTBED_ConfigureSharedServiceMessage *) message;
+  msg_size = ntohs (message->size);
+  if (msg_size <= sizeof (struct GNUNET_TESTBED_ConfigureSharedServiceMessage))
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
+  service_name_size = msg_size - 
+    sizeof (struct GNUNET_TESTBED_ConfigureSharedServiceMessage);
+  service_name = (char *) &msg[1];
+  if ('\0' != service_name[service_name_size - 1])
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
+  LOG_DEBUG ("Received service sharing request for %s, with %d peers\n",
+             service_name, ntohl (msg->num_peers));
+  if (ntohl (msg->host_id) != master_context->host_id)
+  {
+    route_message (ntohl (msg->host_id), message);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+  ss = GNUNET_malloc (sizeof (struct SharedService));
+  ss->name = strdup (service_name);
+  ss->num_shared = ntohl (msg->num_peers);
+  GNUNET_CRYPTO_hash (ss->name, service_name_size, &hash);
+  GNUNET_CONTAINER_multihashmap_put (ss_map, &hash, ss,
+                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
+ * Iterator over hash map entries.
+ *
+ * @param cls closure
+ * @param key current key code
+ * @param value value in the hash map
+ * @return GNUNET_YES if we should continue to
+ *         iterate,
+ *         GNUNET_NO if not.
+ */
+static int 
+ss_map_free_iterator (void *cls,
+                      const struct GNUNET_HashCode * key, void *value)
+{
+  struct SharedService *ss = value;
+
+  GNUNET_CONTAINER_multihashmap_remove (ss_map, key, value);
+  GNUNET_free (ss->name);
+  GNUNET_free (ss);
+  return GNUNET_YES;
+}
+
+
 /**
  * Task to clean up and shutdown nicely
  *
@@ -350,6 +471,9 @@ shutdown_task (void *cls,
   shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
   GNUNET_SCHEDULER_shutdown ();
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
+  (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
+                                                NULL);
+  GNUNET_CONTAINER_multihashmap_destroy (ss_map);
   if (NULL != fh)
   {
     GNUNET_DISK_file_close (fh);
@@ -404,7 +528,9 @@ testbed_run (void *cls,
     {
       {&handle_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_INIT,
        sizeof (struct GNUNET_TESTBED_InitMessage)},
-      {&handle_addhost, NULL, GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST, 0},
+      {&handle_add_host, NULL, GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST, 0},
+      {&handle_configure_shared_service, NULL,
+       GNUNET_MESSAGE_TYPE_TESTBED_SERVICESHARE, 0},
       {NULL}
     };
 
@@ -412,7 +538,8 @@ testbed_run (void *cls,
                               message_handlers);
   GNUNET_SERVER_disconnect_notify (server,
                                    &client_disconnect_cb,
-                                   NULL);  
+                                   NULL);
+  ss_map = GNUNET_CONTAINER_multihashmap_create (5);
   fh = GNUNET_DISK_get_handle_from_native (stdin);
   if (NULL == fh)
     shutdown_task_id = 
index 680649be1bf59a5d472310564d3ad0c9881841f7..17da85952889ce329d53fc4db9bf565483e21aaf 100644 (file)
@@ -96,6 +96,7 @@ struct GNUNET_TESTBED_AddHostMessage
 /**
  * Confirmation from the service that adding a host
  * worked (or failed).
+ * FIXME: Where is this required?
  */
 struct GNUNET_TESTBED_HostConfirmedMessage
 {
index 4787ea25a1f433757eddd62f590a7412ef919ef4..094334e58dcd148fc99b91ae774c8d3f7f445ef1 100644 (file)
@@ -307,7 +307,20 @@ GNUNET_TESTBED_controller_configure_sharing (struct GNUNET_TESTBED_Controller *c
                                             const char *service_name,
                                             uint32_t num_peers)
 {
-  GNUNET_break (0);
+  struct GNUNET_TESTBED_ConfigureSharedServiceMessage *msg;
+  uint16_t service_name_size;
+  uint16_t msg_size;
+  
+  service_name_size = strlen (service_name) + 1;
+  msg_size = sizeof (struct GNUNET_TESTBED_ConfigureSharedServiceMessage)
+    + service_name_size;
+  msg = GNUNET_malloc (msg_size);
+  msg->header.size = htons (msg_size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_SERVICESHARE);
+  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (controller->host));
+  msg->num_peers = htonl (num_peers);
+  memcpy (&msg[1], service_name, service_name_size);
+  queue_message (controller, (struct GNUNET_MessageHeader *) msg);
 }