(no commit message)
[oweals/gnunet.git] / src / transport / test_plugin_transport_http.c
index 0ce1766c959f872c7100bb178fe2b11442e10864..2e540bd5406f2ede57f0af58cc012cd8b0afb1a2 100644 (file)
 #define VERBOSE GNUNET_YES
 #define DEBUG GNUNET_YES
 
+#define PLUGIN libgnunet_plugin_transport_template
+
 /**
  * How long until we give up on transmitting the message?
  */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90)
 
 /**
  * How long until we give up on transmitting the message?
  */
-#define STAT_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
+#define STAT_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
 
 /**
  * Our public key.
  */
 /* static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; */
 
+/**
+ * Our public key.
+ */
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
+
 /**
  * Our identity.
  */
@@ -67,6 +74,7 @@ static struct GNUNET_PeerIdentity my_identity;
  */
 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
 
+
 /**
  * Our scheduler.
  */
@@ -99,9 +107,13 @@ static struct GNUNET_TRANSPORT_PluginEnvironment env;
 static struct GNUNET_TRANSPORT_PluginFunctions *api;
 
 /**
- * ID of the task controlling the locking between two hostlist tests
+ * ID of the task controlling the testcase timeout
  */
-static GNUNET_SCHEDULER_TaskIdentifier ti_check_stat;
+static GNUNET_SCHEDULER_TaskIdentifier ti_timeout;
+
+#if 0
+static GNUNET_SCHEDULER_TaskIdentifier ti_download;
+#endif
 
 static unsigned int timeout_count;
 
@@ -110,6 +122,10 @@ static unsigned int timeout_count;
  */
 static int fail;
 
+//static int done;
+
+pid_t pid;
+
 /**
  * Initialize Environment for this plugin
  */
@@ -136,6 +152,34 @@ notify_address (void *cls,
 
 }
 
+/**
+ * Simple example test that invokes
+ * the check_address function of the plugin.
+ */
+/* FIXME: won't work on IPv6 enabled systems where IPv4 mapping
+ * isn't enabled (eg. FreeBSD > 4)[TESTING]
+WEAKRANDOM = YES
+ */
+static void
+shutdown_clean ()
+{
+/*  if (stat_get_handle != NULL)
+  {
+    GNUNET_STATISTICS_get_cancel(stat_get_handle);
+  }*/
+
+  /* if ( NULL!=stats )GNUNET_STATISTICS_destroy (stats, GNUNET_YES); */
+  if (ti_timeout != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel(sched,ti_timeout);
+  ti_timeout = GNUNET_SCHEDULER_NO_TASK;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Unloading http plugin\n");
+  GNUNET_assert (NULL == GNUNET_PLUGIN_unload ("libgnunet_plugin_transport_http", api));
+  
+  GNUNET_SCHEDULER_shutdown(sched);
+  /* FIXME: */ fail = GNUNET_NO;
+  return;
+}
 
 static void
 setup_plugin_environment ()
@@ -150,22 +194,39 @@ setup_plugin_environment ()
   env.max_connections = max_connect_per_transport;
 }
 
-/**
- * Simple example test that invokes
- * the check_address function of the plugin.
- */
-/* FIXME: won't work on IPv6 enabled systems where IPv4 mapping
- * isn't enabled (eg. FreeBSD > 4)
- */
+#if 0
+static int
+process_stat (void *cls,
+              const char *subsystem,
+              const char *name,
+              uint64_t value,
+              int is_persistent)
+{
+  stat_get_handle = NULL;
+  if (value==1)
+    {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown, plugin failed \n");
+    fail = GNUNET_YES;
+    shutdown_clean();
+    return GNUNET_YES;
+    }
+  if (value==2)
+    {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown, plugin not failed \n");
+    shutdown_clean();
+    return GNUNET_YES;
+    }
+  return GNUNET_YES;
+}
+#endif
+
+#if 0
 static void
-shutdown_clean ()
+cont_func (void *cls, int success)
 {
-  GNUNET_assert (NULL ==
-                 GNUNET_PLUGIN_unload ("libgnunet_plugin_transport_http",
-                                       api));
-  GNUNET_SCHEDULER_shutdown(sched);
-  return;
+  stat_get_handle = NULL;
 }
+#endif
 
 /**
  * Task that checks if we should try to download a hostlist.
@@ -173,14 +234,14 @@ shutdown_clean ()
  * this task again for a later time.
  */
 static void
-task_check_stat (void *cls,
+task_timeout (void *cls,
             const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  ti_check_stat = GNUNET_SCHEDULER_NO_TASK;
+  ti_timeout = GNUNET_SCHEDULER_NO_TASK;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
 
-  if ( timeout_count > 5 )
+  if ( timeout_count > 15 )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testcase timeout\n",  timeout_count);
     fail = GNUNET_YES;
@@ -189,10 +250,215 @@ task_check_stat (void *cls,
   }
   timeout_count++;
 
-  ti_check_stat = GNUNET_SCHEDULER_add_delayed (sched, STAT_INTERVALL, &task_check_stat, NULL);
+/*  stat_get_handle = GNUNET_STATISTICS_get (stats,
+                                           "http-transport",
+                                           gettext_noop("shutdown"),
+                                           GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
+                                           &cont_func,
+                                           &process_stat,
+                                           NULL);*/
+
+  ti_timeout = GNUNET_SCHEDULER_add_delayed (sched, STAT_INTERVALL, &task_timeout, NULL);
   return;
 }
 
+#if 0
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+  size_t retcode;
+
+  /* in real-world cases, this would probably get this data differently
+     as this fread() stuff is exactly what the library already would do
+     by default internally */
+  retcode = fread(ptr, size, nmemb, stream);
+
+  fprintf(stderr, "*** We read %d bytes from file\n", (int) retcode);
+
+  return retcode;
+}
+#endif
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+#if 0
+static size_t
+putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+  size_t len;
+
+  struct CBC  * cbc = ptr;
+
+  len = strlen(cbc->buf);
+
+  if (( cbc->pos == len) && (len < (size * nmemb)))
+    return 0;
+  memcpy(stream, cbc->buf, len+1);
+  cbc->pos = len;
+  return len;
+}
+#endif
+
+#if 0
+static int execute (char * url)
+{
+  done = 0;
+  CURLM *multi_handle;
+  CURL *curl_handle;
+  CURLMsg *msg;
+  int msgs_left;
+  FILE * hd_src ;
+  int hd ;
+  struct stat file_info;
+  int still_running;
+  char buf[2048];
+  struct CBC cbc;
+
+  char *file = "curl.c";
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+
+  const char * txt = "Hello World!";
+  memcpy(cbc.buf,txt,strlen(txt)+1);
+  //fprintf(stderr,"%s %u\n",src,strlen(src));
+
+  /* get the file size of the local file */
+  hd = open(file, O_RDONLY) ;
+  fstat(hd, &file_info);
+  close(hd) ;
+
+  /* get a FILE * of the same file, could also be made with
+     fdopen() from the previous descriptor, but hey this is just
+     an example! */
+  hd_src = fopen(file, "rb");
+  //printf("size: %u \n", (curl_off_t) file_info.st_size);
+
+  /* get a curl handle */
+  curl_handle = curl_easy_init();
+  if( NULL == curl_handle)
+  {
+    printf("easy_init failed \n");
+    return 0;
+  }
+  curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
+  //curl_easy_setopt (curl_handle, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  //curl_easy_setopt (curl_handle, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (curl_handle, CURLOPT_READFUNCTION, &putBuffer);
+  curl_easy_setopt (curl_handle, CURLOPT_READDATA, &cbc);
+  curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1L);
+  curl_easy_setopt(curl_handle, CURLOPT_PUT, 1L);
+  curl_easy_setopt(curl_handle, CURLOPT_URL, url);
+  curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) strlen(txt));
+
+  //curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
+
+  multi_handle = curl_multi_init();
+  curl_multi_add_handle(multi_handle, curl_handle);
+
+  while(CURLM_CALL_MULTI_PERFORM ==
+        curl_multi_perform(multi_handle, &still_running));
+
+  while(still_running)
+  {
+      struct timeval timeout;
+      int rc; /* select() return code */
+
+      fd_set fdread;
+      fd_set fdwrite;
+      fd_set fdexcep;
+      int maxfd = -1;
+
+      FD_ZERO(&fdread);
+      FD_ZERO(&fdwrite);
+      FD_ZERO(&fdexcep);
+
+      /* set a suitable timeout to play around with */
+      timeout.tv_sec = 1;
+      timeout.tv_usec = 0;
+
+      /* get file descriptors from the transfers */
+      curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+      /* In a real-world program you OF COURSE check the return code of the
+         function calls.  On success, the value of maxfd is guaranteed to be
+         greater or equal than -1.  We call select(maxfd + 1, ...), specially in
+         case of (maxfd == -1), we call select(0, ...), which is basically equal
+         to sleep. */
+
+      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+      switch(rc)
+      {
+      case -1:
+        /* select error */
+        break;
+      case 0:
+        /* timeout, do something else */
+        break;
+      default:
+        /* one or more of curl's file descriptors say there's data to read
+           or write */
+        while(CURLM_CALL_MULTI_PERFORM ==
+              curl_multi_perform(multi_handle, &still_running));
+        break;
+      }
+  }
+
+  /* See how the transfers went */
+  while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
+    if (msg->msg == CURLMSG_DONE) {
+      int idx, found = 0;
+
+      /* Find out which handle this message is about */
+      for (idx=0; idx<1; idx++) {
+        found = (msg->easy_handle == curl_handle);
+        if(found)
+          break;
+      }
+
+      switch (idx) {
+      case 0:
+        printf("HTTP transfer completed with status %d\n", msg->data.result);
+        break;
+      }
+    }
+  }
+
+  curl_multi_cleanup(multi_handle);
+
+  curl_easy_cleanup(curl_handle);
+
+  fclose(hd_src); /* close the local file */
+  return 0;
+}
+#endif
+
+#if 0
+/**
+ * Task that checks if we should try to download a hostlist.
+ * If so, we initiate the download, otherwise we schedule
+ * this task again for a later time.
+ */
+static void
+task_download (void *cls,
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  ti_download = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+
+  execute ("http://localhost:12389/Q7BO0ELEHAT8JNENQ90112G0TACH2H2HIR4IJ2JQ28U6FV14CK44EVP26FVAEALO7HIRJFLFE6709RP6IITM64B0FU7J4RA8KPNDKN8");
+
+  return;
+}
+#endif
+
 /**
  * Runs the test.
  *
@@ -207,25 +473,73 @@ run (void *cls,
      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 {
   char * libname;
-
   sched = s;
   cfg = c;
+  char *keyfile;
+  unsigned long long tneigh;
+
+  /* settings up statistics */
+/*  stats = GNUNET_STATISTICS_create (sched, "http-transport", cfg);
+  if (NULL == stats)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Failed to retrieve statistics handle\n"));
+    fail = GNUNET_YES;
+    shutdown_clean();
+    return ;
+  }*/
+
+  /* parse configuration */
+  if ((GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_number (c,
+                                              "TRANSPORT",
+                                              "NEIGHBOUR_LIMIT",
+                                              &tneigh)) ||
+      (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_filename (c,
+                                                "GNUNETD",
+                                                "HOSTKEY", &keyfile)))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _
+                  ("Transport service is lacking key configuration settings.  Exiting.\n"));
+      GNUNET_SCHEDULER_shutdown (s);
+      return;
+    }
+  max_connect_per_transport = (uint32_t) tneigh;
+  my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
+  GNUNET_free (keyfile);
+  if (my_private_key == NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _
+                  ("Transport service could not access hostkey.  Exiting.\n"));
+      GNUNET_SCHEDULER_shutdown (s);
+      return;
+    }
+  GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
+  GNUNET_CRYPTO_hash (&my_public_key,
+                      sizeof (my_public_key), &my_identity.hashPubKey);
 
   /* load plugins... */
   setup_plugin_environment ();
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading HTTP transport plugin\n"));
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading HTTP transport plugin `%s'\n"),"libgnunet_plugin_transport_http");
   GNUNET_asprintf (&libname, "libgnunet_plugin_transport_http");
-
   api = GNUNET_PLUGIN_load (libname, &env);
   GNUNET_free (libname);
   if (api == NULL)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Failed to load transport plugin for udp\n"));
+                _("Failed to load transport plugin for http\n"));
+    fail = GNUNET_YES;
     return;
   }
 
-  ti_check_stat = GNUNET_SCHEDULER_add_now (sched, &task_check_stat, NULL);
+  ti_timeout = GNUNET_SCHEDULER_add_now (sched, &task_timeout, NULL);
+  //ti_download = GNUNET_SCHEDULER_add_now (sched, &task_download, NULL);
+
+  return;
+
 }
 
 
@@ -239,6 +553,7 @@ run (void *cls,
 int
 main (int argc, char *const *argv)
 {
+
   static struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
@@ -262,14 +577,38 @@ main (int argc, char *const *argv)
                     "WARNING",
 #endif
                     NULL);
+/*  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting statistics service\n");
+  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
+                                 "gnunet-service-statistics",
+                                 "-L", "DEBUG",
+                                 "-c", "test_plugin_transport_data_http.conf", NULL);
+
+  fail = GNUNET_NO;
+  if (pid==-1 )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to start statistics service\n");
+    fail = GNUNET_YES;
+    return fail;
+  }*/
+
   ret = (GNUNET_OK ==
          GNUNET_PROGRAM_run (5,
                              argv_prog,
                              "test_plugin_transport_http",
-                             "testcase", options, &run, NULL)) ? GNUNET_YES : 1;
-  GNUNET_DISK_directory_remove ("/tmp/test_plugin_transport_http");
+                             "testcase", options, &run, NULL)) ? GNUNET_NO : GNUNET_YES;
+
+    GNUNET_DISK_directory_remove ("/tmp/test_plugin_transport_http");
+
 
-  return GNUNET_NO;
+/*  if (0 != PLIBC_KILL (pid, SIGTERM))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "Failed to kill statistics service");
+    fail = GNUNET_YES;
+  }
+  if (GNUNET_OS_process_wait(pid) != GNUNET_OK)
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Killed statistics service\n");*/
+  return fail;
 }
 
 /* end of test_plugin_transport_http.c */