gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r22313 - in gnunet/src: include testbed


From: gnunet
Subject: [GNUnet-SVN] r22313 - in gnunet/src: include testbed
Date: Tue, 26 Jun 2012 21:07:46 +0200

Author: harsha
Date: 2012-06-26 21:07:46 +0200 (Tue, 26 Jun 2012)
New Revision: 22313

Modified:
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/include/gnunet_testbed_service.h
   gnunet/src/testbed/gnunet-service-testbed.c
   gnunet/src/testbed/testbed.h
   gnunet/src/testbed/testbed_api.c
   gnunet/src/testbed/testbed_api_hosts.c
   gnunet/src/testbed/testbed_api_hosts.h
Log:
testbed host registration

Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2012-06-26 19:03:44 UTC (rev 
22312)
+++ gnunet/src/include/gnunet_protocols.h       2012-06-26 19:07:46 UTC (rev 
22313)
@@ -1346,7 +1346,7 @@
 /**
  * Message to signal that a add host succeeded
  */
-#define GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTSUCCESS 462
+#define GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM 462
 
 /**
  * Message to configure a service to be shared among peers

Modified: gnunet/src/include/gnunet_testbed_service.h
===================================================================
--- gnunet/src/include/gnunet_testbed_service.h 2012-06-26 19:03:44 UTC (rev 
22312)
+++ gnunet/src/include/gnunet_testbed_service.h 2012-06-26 19:07:46 UTC (rev 
22313)
@@ -448,6 +448,56 @@
 
 
 /**
+ * Opaque handle for host registration
+ */
+struct GNUNET_TESTBED_HostRegistrationHandle;
+
+
+/**
+ * Callback which will be called to after a host registration succeeded or 
failed
+ *
+ * @param cls the closure
+ * @param emsg the error message; NULL if host registration is successful
+ */
+typedef void (* GNUNET_TESTBED_HostRegistrationCompletion) (void *cls, 
+                                                            const char *emsg);
+
+
+/**
+ * Register a host with the controller
+ *
+ * @param controller the controller handle
+ * @param host the host to register
+ * @param cc the completion callback to call to inform the status of
+ *          registration. After calling this callback the registration handle
+ *          will be invalid. Cannot be NULL
+ * @param cc_cls the closure for the cc
+ * @return handle to the host registration which can be used to cancel the
+ *           registration; NULL if another registration handle is present and
+ *           is not cancelled
+ */
+struct GNUNET_TESTBED_HostRegistrationHandle *
+GNUNET_TESTBED_register_host (struct GNUNET_TESTBED_Controller *controller,
+                              struct GNUNET_TESTBED_Host *host,
+                              GNUNET_TESTBED_HostRegistrationCompletion cc,
+                              void *cc_cls);
+
+
+/**
+ * Cancel the pending registration. Note that the registration message will
+ * already be queued to be sent to the service, cancellation has only the
+ * effect that the registration completion callback for the registration is
+ * never called and from our perspective the host is not registered until the
+ * completion callback is called.
+ *
+ * @param handle the registration handle to cancel
+ */
+void
+GNUNET_TESTBED_cancel_registration (struct 
GNUNET_TESTBED_HostRegistrationHandle
+                                    *handle);
+
+
+/**
  * Create a link from a 'master' controller to a slave controller.
  * Whenever the master controller is asked to start a peer at the
  * given 'delegated_host', it will delegate the request to the

Modified: gnunet/src/testbed/gnunet-service-testbed.c
===================================================================
--- gnunet/src/testbed/gnunet-service-testbed.c 2012-06-26 19:03:44 UTC (rev 
22312)
+++ gnunet/src/testbed/gnunet-service-testbed.c 2012-06-26 19:07:46 UTC (rev 
22313)
@@ -271,11 +271,6 @@
 
 
 /**
- * 
- */
-
-
-/**
  * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
  *
  * @param cls NULL
@@ -363,23 +358,50 @@
   host = GNUNET_TESTBED_host_create_with_id (host_id, hostname, username,
                                              ntohs (msg->ssh_port));
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  if (GNUNET_OK == host_list_add (host))
-    return;
-  /* We are unable to add a host */
-  emsg = "A host exists with given host-id";
-  GNUNET_TESTBED_host_destroy (host);
-  reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage)
-    + strlen (emsg) + 1;
-  reply = GNUNET_malloc (reply_size);
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTSUCCESS);
+  reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage);
+  if (GNUNET_OK != host_list_add (host))
+  {    
+    /* We are unable to add a host */  
+    emsg = "A host exists with given host-id";
+    LOG_DEBUG ("%s: %u", emsg, host_id);
+    GNUNET_TESTBED_host_destroy (host);
+    reply_size += strlen (emsg) + 1;
+    reply = GNUNET_malloc (reply_size);
+    memcpy (&reply[1], emsg, strlen (emsg) + 1);
+  }
+  else
+    reply = GNUNET_malloc (reply_size);  
+  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM);
   reply->header.size = htons (reply_size);
-  reply->host_id = htonl (host_id);
-  memcpy (&reply[1], emsg, strlen (emsg) + 1);
+  reply->host_id = htonl (host_id);  
   queue_message (client, (struct GNUNET_MessageHeader *) reply);
 }
 
 
 /**
+ * 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.
+ */
+int ss_exists_iterator (void *cls,
+                        const struct GNUNET_HashCode * key,
+                        void *value)
+{
+  struct SharedService *queried_ss = cls;
+  struct SharedService *ss = value;
+
+  if (0 == strcmp (ss->name, queried_ss->name))
+    return GNUNET_NO;
+  else
+    return GNUNET_YES;
+}
+
+/**
  * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages
  *
  * @param cls NULL
@@ -423,13 +445,24 @@
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
   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);
+  if (GNUNET_SYSERR == 
+      GNUNET_CONTAINER_multihashmap_get_multiple (ss_map, &hash,
+                                                  &ss_exists_iterator, ss))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Service %s already configured as a shared service. "
+         "Ignoring service sharing request \n", ss->name);
+    GNUNET_free (ss->name);
+    GNUNET_free (ss);
+    return;
+  }
   GNUNET_CONTAINER_multihashmap_put (ss_map, &hash, ss,
-                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);  
 }
 
 
@@ -474,6 +507,7 @@
   (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
                                                 NULL);
   GNUNET_CONTAINER_multihashmap_destroy (ss_map);
+  /* Clear host array */
   if (NULL != fh)
   {
     GNUNET_DISK_file_close (fh);
@@ -482,6 +516,7 @@
   for (host_id = 0; host_id < host_list_size; host_id++)
     if (NULL != host_list[host_id])
       GNUNET_TESTBED_host_destroy (host_list[host_id]);
+  GNUNET_free (host_list);
   GNUNET_free_non_null (master_context);
   master_context = NULL;
 }

Modified: gnunet/src/testbed/testbed.h
===================================================================
--- gnunet/src/testbed/testbed.h        2012-06-26 19:03:44 UTC (rev 22312)
+++ gnunet/src/testbed/testbed.h        2012-06-26 19:07:46 UTC (rev 22313)
@@ -54,7 +54,6 @@
    * is interested in.  In NBO.
    */
   uint64_t event_mask GNUNET_PACKED;
-
 };
 
 

Modified: gnunet/src/testbed/testbed_api.c
===================================================================
--- gnunet/src/testbed/testbed_api.c    2012-06-26 19:03:44 UTC (rev 22312)
+++ gnunet/src/testbed/testbed_api.c    2012-06-26 19:07:46 UTC (rev 22313)
@@ -35,11 +35,19 @@
 #include "testbed.h"
 #include "testbed_api_hosts.h"
 
-
+/**
+ * Generic logging shorthand
+ */
 #define LOG(kind, ...)                          \
   GNUNET_log_from (kind, "testbed-api", __VA_ARGS__);
 
+/**
+ * Debug logging
+ */
+#define LOG_DEBUG(...)                          \
+  LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__);
 
+
 /**
  * The message queue for sending messages to the controller service
  */
@@ -63,6 +71,45 @@
 
 
 /**
+ * Structure for a controller link
+ */
+struct ControllerLink
+{
+  /**
+   * The next ptr for DLL
+   */
+  struct ControllerLink *next;
+
+  /**
+   * The prev ptr for DLL
+   */
+  struct ControllerLink *prev;
+
+  /**
+   * The host which will be referred in the peer start request. This is the
+   * host where the peer should be started
+   */
+  struct GNUNET_TESTBED_Host *delegated_host;
+
+  /**
+   * The host which will contacted to delegate the peer start request
+   */
+  struct GNUNET_TESTBED_Host *slave_host;
+
+  /**
+   * The configuration to be used to connect to slave host
+   */
+  const struct GNUNET_CONFIGURATION_Handle *slave_cfg;
+
+  /**
+   * GNUNET_YES if the slave should be started (and stopped) by us; GNUNET_NO
+   * if we are just allowed to use the slave via TCP/IP
+   */
+  int is_subordinate;
+};
+
+
+/**
  * Handle to interact with a GNUnet testbed controller.  Each
  * controller has at least one master handle which is created when the
  * controller is created; this master handle interacts with the
@@ -115,11 +162,27 @@
   struct MessageQueue *mq_tail;
 
   /**
+   * The head of the ControllerLink list
+   */
+  struct ControllerLink *cl_head;
+
+  /**
+   * The tail of the ControllerLink list
+   */
+  struct ControllerLink *cl_tail;
+
+  /**
    * The client transmit handle
    */
   struct GNUNET_CLIENT_TransmitHandle *th;
 
   /**
+   * The host registration handle; NULL if no current registration requests are
+   * present 
+   */
+  struct GNUNET_TESTBED_HostRegistrationHandle *rh;
+
+  /**
    * The controller event mask
    */
   uint64_t event_mask;
@@ -131,8 +194,84 @@
 };
 
 
+/**
+ * handle for host registration
+ */
+struct GNUNET_TESTBED_HostRegistrationHandle
+{
+  /**
+   * The host being registered
+   */
+  struct GNUNET_TESTBED_Host *host;
 
+  /**
+   * The Registartion completion callback
+   */
+  GNUNET_TESTBED_HostRegistrationCompletion cc;
+
+  /**
+   * The closure for above callback
+   */
+  void *cc_cls;
+};
+
+
 /**
+ * Handler for GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM message from
+ * controller (testbed service)
+ *
+ * @param c the controller handler
+ * @param msg message received
+ * @return GNUNET_YES if we can continue receiving from service; GNUNET_NO if
+ *           not
+ */
+static int
+handle_addhostconfirm (struct GNUNET_TESTBED_Controller *c,
+                       const struct GNUNET_TESTBED_HostConfirmedMessage *msg)
+{
+  struct GNUNET_TESTBED_HostRegistrationHandle *rh;
+  char *emsg;
+  uint16_t msg_size;
+
+  rh = c->rh;
+  if (NULL == rh)
+  {  
+    return GNUNET_OK;    
+  }
+  if (GNUNET_TESTBED_host_get_id_ (rh->host) != ntohl (msg->host_id))
+  {
+    LOG_DEBUG ("Mismatch in host id's %u, %u of host confirm msg\n",
+               GNUNET_TESTBED_host_get_id_ (rh->host), ntohl (msg->host_id));
+    return GNUNET_OK;
+  }
+  c->rh = NULL;
+  msg_size = ntohs (msg->header.size);
+  if (sizeof (struct GNUNET_TESTBED_HostConfirmedMessage) == msg_size)
+  {
+    LOG_DEBUG ("Host %u successfully registered\n", ntohl (msg->host_id));
+    GNUNET_TESTBED_mark_host_as_registered_  (rh->host);
+    rh->cc (rh->cc_cls, NULL);
+    GNUNET_free (rh);
+    return GNUNET_OK;
+  } 
+  /* We have an error message */
+  emsg = (char *) &msg[1];
+  if ('\0' != emsg[msg_size - 
+                   sizeof (struct GNUNET_TESTBED_HostConfirmedMessage)])
+  {
+    GNUNET_break (0);
+    GNUNET_free (rh);
+    return GNUNET_NO;
+  }  
+  LOG (GNUNET_ERROR_TYPE_ERROR, _("Adding host %u failed with error: %s\n"),
+       ntohl (msg->host_id), emsg);
+  rh->cc (rh->cc_cls, emsg);
+  GNUNET_free (rh);
+  return GNUNET_OK;
+}
+
+
+/**
  * Handler for messages from controller (testbed service)
  *
  * @param cls the controller handler
@@ -141,16 +280,29 @@
 static void 
 message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
 {
-  struct GNUNET_TESTBED_Controller *c = cls;
+  struct GNUNET_TESTBED_Controller *c = cls;  
+  int status;
 
   /* FIXME: Add checks for message integrity */
+  if (NULL == msg)
+  {
+    LOG_DEBUG ("Receive timed out or connection to service dropped\n");
+    return;
+  }
+  status = GNUNET_OK;
   switch (ntohs (msg->type))
   {
+  case GNUNET_MESSAGE_TYPE_TESTBED_ADDHOSTCONFIRM:
+    status =
+      handle_addhostconfirm (c, (const struct
+                                 GNUNET_TESTBED_HostConfirmedMessage *) msg);  
 
+    break;
   default:
     GNUNET_break (0);
   }
-  GNUNET_CLIENT_receive (c->client, &message_handler, c,
-                         GNUNET_TIME_UNIT_FOREVER_REL);
+  if (GNUNET_OK == status)
+    GNUNET_CLIENT_receive (c->client, &message_handler, c,
+                           GNUNET_TIME_UNIT_FOREVER_REL);
 }
 
 
@@ -356,6 +508,87 @@
 
 
 /**
+ * Register a host with the controller
+ *
+ * @param controller the controller handle
+ * @param host the host to register
+ * @param cc the completion callback to call to inform the status of
+ *          registration. After calling this callback the registration handle
+ *          will be invalid. Cannot be NULL.
+ * @param cc_cls the closure for the cc
+ * @return handle to the host registration which can be used to cancel the
+ *           registration 
+ */
+struct GNUNET_TESTBED_HostRegistrationHandle *
+GNUNET_TESTBED_register_host (struct GNUNET_TESTBED_Controller *controller,
+                              struct GNUNET_TESTBED_Host *host,
+                              GNUNET_TESTBED_HostRegistrationCompletion cc,
+                              void *cc_cls)
+{
+  struct GNUNET_TESTBED_HostRegistrationHandle *rh;
+  struct GNUNET_TESTBED_AddHostMessage *msg;
+  const char *username;
+  const char *hostname;
+  uint16_t msg_size;
+  uint16_t user_name_length;
+
+  if (NULL != controller->rh)
+    return NULL;
+  hostname = GNUNET_TESTBED_host_get_hostname_ (host);
+  if (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (host))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Host hostname: %s already registered\n",
+         (NULL == hostname) ? "localhost" : hostname);
+    return NULL;
+  }  
+  rh = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HostRegistrationHandle));
+  rh->host = host;
+  GNUNET_assert (NULL != cc);
+  rh->cc = cc;
+  rh->cc_cls = cc_cls;
+  controller->rh = rh;
+  username = GNUNET_TESTBED_host_get_username_ (host);
+  msg_size = (sizeof (struct GNUNET_TESTBED_AddHostMessage));
+  user_name_length = 0;
+  if (NULL != username)
+  {
+    user_name_length = strlen (username) + 1;
+    msg_size += user_name_length;
+  }
+  /* FIXME: what happens when hostname is NULL? localhost */
+  GNUNET_assert (NULL != hostname);
+  msg_size += strlen (hostname) + 1;
+  msg = GNUNET_malloc (msg_size);
+  msg->header.size = htons (msg_size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST);
+  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (host));
+  msg->ssh_port = htons (GNUNET_TESTBED_host_get_ssh_port_ (host));
+  msg->user_name_length = htons (user_name_length);
+  if (NULL != username)
+    memcpy (&msg[1], username, user_name_length);
+  strcpy (((void *) msg) + user_name_length, hostname);
+  queue_message (controller, (struct GNUNET_MessageHeader *) msg);
+  return rh;
+}
+
+
+/**
+ * Cancel the pending registration. Note that if the registration message is
+ * already sent to the service the cancellation has only the effect that the
+ * registration completion callback for the registration is never called.
+ *
+ * @param handle the registration handle to cancel
+ */
+void
+GNUNET_TESTBED_cancel_registration (struct 
GNUNET_TESTBED_HostRegistrationHandle
+                                    *handle)
+{
+  GNUNET_break (0);
+}
+
+
+/**
  * Create a link from a 'master' controller to a slave controller.
  * Whenever the master controller is asked to start a peer at the
  * given 'delegated_host', it will delegate the request to the

Modified: gnunet/src/testbed/testbed_api_hosts.c
===================================================================
--- gnunet/src/testbed/testbed_api_hosts.c      2012-06-26 19:03:44 UTC (rev 
22312)
+++ gnunet/src/testbed/testbed_api_hosts.c      2012-06-26 19:07:46 UTC (rev 
22313)
@@ -72,6 +72,11 @@
    * The port which is to be used for SSH
    */
   uint16_t port;
+
+  /**
+   * Set this flag to 1 if host is registered with a controller; 0 if not
+   */
+  uint8_t is_registered;
 };
 
 
@@ -126,7 +131,7 @@
 
 
 /**
- * Obtain a host's unique global ID.
+ * Obtain the host's unique global ID.
  * 
  * @param host handle to the host, NULL means 'localhost'
  * @return id global host ID assigned to the host (0 is
@@ -140,6 +145,45 @@
 
 
 /**
+ * Obtain the host's hostname.
+ * 
+ * @param host handle to the host, NULL means 'localhost'
+ * @return hostname of the host
+ */
+const char *
+GNUNET_TESTBED_host_get_hostname_ (const struct GNUNET_TESTBED_Host *host)
+{
+  return host->hostname;
+}
+
+
+/**
+ * Obtain the host's username
+ * 
+ * @param host handle to the host, NULL means 'localhost'
+ * @return username to login to the host
+ */
+const char *
+GNUNET_TESTBED_host_get_username_ (const struct GNUNET_TESTBED_Host *host)
+{
+  return host->username;
+}
+
+
+/**
+ * Obtain the host's ssh port
+ * 
+ * @param host handle to the host, NULL means 'localhost'
+ * @return username to login to the host
+ */
+uint16_t
+GNUNET_TESTBED_host_get_ssh_port_ (const struct GNUNET_TESTBED_Host *host)
+{
+  return host->port;
+}
+
+
+/**
  * Create a host to run peers and controllers on.
  * 
  * @param id global host ID assigned to the host; 0 is
@@ -336,4 +380,30 @@
   GNUNET_free (handle);
 }
 
+
+/**
+ * Marks a host as registered with a controller
+ *
+ * @param host the host to mark
+ */
+void
+GNUNET_TESTBED_mark_host_as_registered_ (struct GNUNET_TESTBED_Host *host)
+{
+  host->is_registered = 1;
+}
+
+
+/**
+ * Checks whether a host has been registered
+ *
+ * @param host the host to check
+ * @return GNUNET_YES if registered; GNUNET_NO if not
+ */
+int
+GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host)
+{
+  return (1 == host->is_registered) ? GNUNET_YES : GNUNET_NO;
+}
+
+
 /* end of testbed_api_hosts.c */

Modified: gnunet/src/testbed/testbed_api_hosts.h
===================================================================
--- gnunet/src/testbed/testbed_api_hosts.h      2012-06-26 19:03:44 UTC (rev 
22312)
+++ gnunet/src/testbed/testbed_api_hosts.h      2012-06-26 19:07:46 UTC (rev 
22313)
@@ -66,6 +66,36 @@
 
 
 /**
+ * Obtain the host's hostname.
+ * 
+ * @param host handle to the host, NULL means 'localhost'
+ * @return hostname of the host
+ */
+const char *
+GNUNET_TESTBED_host_get_hostname_ (const struct GNUNET_TESTBED_Host *host);
+
+
+/**
+ * Obtain the host's username
+ * 
+ * @param host handle to the host, NULL means 'localhost'
+ * @return username to login to the host
+ */
+const char *
+GNUNET_TESTBED_host_get_username_ (const struct GNUNET_TESTBED_Host *host);
+
+
+/**
+ * Obtain the host's ssh port
+ * 
+ * @param host handle to the host, NULL means 'localhost'
+ * @return username to login to the host
+ */
+uint16_t
+GNUNET_TESTBED_host_get_ssh_port_ (const struct GNUNET_TESTBED_Host *host);
+
+
+/**
  * Opaque wrapper around GNUNET_HELPER_Handle
  */
 struct GNUNET_TESTBED_HelperHandle;
@@ -94,5 +124,24 @@
 void
 GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle);
 
+
+/**
+ * Marks a host as registered with a controller
+ *
+ * @param host the host to mark
+ */
+void
+GNUNET_TESTBED_mark_host_as_registered_ (struct GNUNET_TESTBED_Host *host);
+
+
+/**
+ * Checks whether a host has been registered
+ *
+ * @param host the host to check
+ * @return GNUNET_YES if registered; GNUNET_NO if not
+ */
+int
+GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host);
+
 #endif
 /* end of testbed_api_hosts.h */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]