gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r23354 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r23354 - gnunet/src/transport
Date: Wed, 22 Aug 2012 12:06:18 +0200

Author: wachs
Date: 2012-08-22 12:06:18 +0200 (Wed, 22 Aug 2012)
New Revision: 23354

Modified:
   gnunet/src/transport/plugin_transport_http_client.c
   gnunet/src/transport/plugin_transport_http_server.c
   gnunet/src/transport/test_transport_api_http_reverse_proxy.conf
Log:
changes


Modified: gnunet/src/transport/plugin_transport_http_client.c
===================================================================
--- gnunet/src/transport/plugin_transport_http_client.c 2012-08-22 08:13:47 UTC 
(rev 23353)
+++ gnunet/src/transport/plugin_transport_http_client.c 2012-08-22 10:06:18 UTC 
(rev 23354)
@@ -55,7 +55,7 @@
 /**
  * Encapsulation of all of the state of the plugin.
  */
-struct Plugin;
+struct HTTP_Client_Plugin;
 
 
 /**
@@ -77,7 +77,7 @@
   /**
    * Pointer to the global plugin struct.
    */
-  struct Plugin *plugin;
+  struct HTTP_Client_Plugin *plugin;
 
   /**
    * The client (used to identify this connection)
@@ -118,7 +118,7 @@
 /**
  * Encapsulation of all of the state of the plugin.
  */
-struct Plugin
+struct HTTP_Client_Plugin
 {
   /**
    * Our environment.
@@ -168,7 +168,7 @@
                   struct GNUNET_TIME_Relative to,
                   GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 {
-  struct Plugin *plugin = cls;
+  struct HTTP_Client_Plugin *plugin = cls;
   int bytes_sent = 0;
 
   GNUNET_assert (plugin != NULL);
@@ -275,9 +275,9 @@
 {
   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
   struct GNUNET_TRANSPORT_PluginFunctions *api;
-  struct Plugin *plugin;
+  struct HTTP_Client_Plugin *plugin;
 
-  plugin = GNUNET_malloc (sizeof (struct Plugin));
+  plugin = GNUNET_malloc (sizeof (struct HTTP_Client_Plugin));
   plugin->env = env;
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
@@ -297,7 +297,7 @@
 LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
 {
   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
-  struct Plugin *plugin = api->cls;
+  struct HTTP_Client_Plugin *plugin = api->cls;
 
   GNUNET_free (plugin);
   GNUNET_free (api);

Modified: gnunet/src/transport/plugin_transport_http_server.c
===================================================================
--- gnunet/src/transport/plugin_transport_http_server.c 2012-08-22 08:13:47 UTC 
(rev 23353)
+++ gnunet/src/transport/plugin_transport_http_server.c 2012-08-22 10:06:18 UTC 
(rev 23354)
@@ -33,6 +33,10 @@
 #include "gnunet_transport_service.h"
 #include "gnunet_transport_plugin.h"
 
+#include "gnunet_container_lib.h"
+#include "gnunet_nat_lib.h"
+#include "microhttpd.h"
+
 #if BUILD_HTTPS
 #define LIBGNUNET_PLUGIN_TRANSPORT_INIT 
libgnunet_plugin_transport_https_server_init
 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE 
libgnunet_plugin_transport_https_server_done
@@ -77,7 +81,7 @@
   /**
    * Pointer to the global plugin struct.
    */
-  struct Plugin *plugin;
+  struct HTTP_Server_Plugin *plugin;
 
   /**
    * The client (used to identify this connection)
@@ -118,7 +122,7 @@
 /**
  * Encapsulation of all of the state of the plugin.
  */
-struct Plugin
+struct HTTP_Server_Plugin
 {
   /**
    * Our environment.
@@ -130,10 +134,127 @@
    */
   struct Session *sessions;
 
+  char *name;
+  char *protocol;
+  char *external_hostname;
+
+  /**
+   * Maximum number of sockets the plugin can use
+   * Each http inbound /outbound connections are two connections
+   */
+  unsigned int max_connections;
+
+  /**
+   * External hostname the plugin can be connected to, can be different to
+   * the host's FQDN, used e.g. for reverse proxying
+   */
+  struct HttpAddress *ext_addr;
+
+  /**
+   * External address length
+   */
+  size_t ext_addr_len;
+
+  /**
+   * use IPv6
+   */
+  uint16_t use_ipv6;
+
+  /**
+   * use IPv4
+   */
+  uint16_t use_ipv4;
+
+  /**
+   * Port used
+   */
+  uint16_t port;
+
+  /**
+   * Task calling transport service about external address
+   */
+  GNUNET_SCHEDULER_TaskIdentifier notify_ext_task;
+
+  /**
+   * NAT handle & address management
+   */
+  struct GNUNET_NAT_Handle *nat;
+
+  /**
+   * List of own addresses
+   */
+
+  /**
+   * IPv4 addresses DLL head
+   */
+  struct HttpAddressWrapper *addr_head;
+
+  /**
+   * IPv4 addresses DLL tail
+   */
+  struct HttpAddressWrapper *addr_tail;
+
+  /**
+   * IPv4 server socket to bind to
+   */
+  struct sockaddr_in *server_addr_v4;
+
+  /**
+   * IPv6 server socket to bind to
+   */
+  struct sockaddr_in6 *server_addr_v6;
+
+
+  /**
+   * MHD IPv4 daemon
+   */
+  struct MHD_Daemon *server_v4;
+
+  /**
+   * MHD IPv4 daemon
+   */
+  struct MHD_Daemon *server_v6;
 };
 
+GNUNET_NETWORK_STRUCT_BEGIN
 
 /**
+ * HTTP addresses including a full URI
+ */
+struct HttpAddress
+{
+  /**
+   * Length of the address following in NBO
+   */
+  uint32_t addr_len GNUNET_PACKED;
+
+  /**
+   * Address following
+   */
+  void *addr GNUNET_PACKED;
+};
+GNUNET_NETWORK_STRUCT_END
+
+/**
+ * Wrapper to manage addresses
+ */
+struct HttpAddressWrapper
+{
+  /**
+   * Linked list next
+   */
+  struct HttpAddressWrapper *next;
+
+  /**
+   * Linked list previous
+   */
+  struct HttpAddressWrapper *prev;
+
+  struct HttpAddress *addr;
+};
+
+
+/**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.   Note that in the case of a
  * peer disconnecting, the continuation MUST be called
@@ -168,7 +289,7 @@
                   struct GNUNET_TIME_Relative to,
                   GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 {
-  struct Plugin *plugin = cls;
+  struct HTTP_Server_Plugin *plugin = cls;
   int bytes_sent = 0;
 
   GNUNET_assert (plugin != NULL);
@@ -264,10 +385,524 @@
   return NULL;
 }
 
+/**
+ * Our external IP address/port mapping has changed.
+ *
+ * @param cls closure, the 'struct LocalAddrList'
+ * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO 
to mean
+ *     the previous (now invalid) one
+ * @param addr either the previous or the new public IP address
+ * @param addrlen actual lenght of the address
+ */
+static void
+server_nat_port_map_callback (void *cls, int add_remove, const struct sockaddr 
*addr,
+                       socklen_t addrlen)
+{
+  GNUNET_assert (cls != NULL);
+  struct HTTP_Server_Plugin *plugin = cls;
 
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   "NPMC called %s to address `%s'\n",
+                   (add_remove == GNUNET_NO) ? "remove" : "add",
+                   GNUNET_a2s (addr, addrlen));
 
+  switch (add_remove)
+  {
+  case GNUNET_YES:
+    //nat_add_address (cls, add_remove, addr, addrlen);
+    break;
+  case GNUNET_NO:
+    //nat_remove_address (cls, add_remove, addr, addrlen);
+    break;
+  }
+}
 
+
+static int
+server_get_addresses (struct HTTP_Server_Plugin *plugin,
+                      const char *serviceName,
+                      const struct GNUNET_CONFIGURATION_Handle *cfg,
+                      struct sockaddr ***addrs, socklen_t ** addr_lens)
+{
+  int disablev6;
+  unsigned long long port;
+  struct addrinfo hints;
+  struct addrinfo *res;
+  struct addrinfo *pos;
+  struct addrinfo *next;
+  unsigned int i;
+  int resi;
+  int ret;
+  struct sockaddr **saddrs;
+  socklen_t *saddrlens;
+  char *hostname;
+
+  *addrs = NULL;
+  *addr_lens = NULL;
+
+  disablev6 = !plugin->use_ipv6;
+
+  port = 0;
+  if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT"))
+  {
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_CONFIGURATION_get_value_number (cfg, serviceName,
+                                                         "PORT", &port));
+    if (port > 65535)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _
+                  ("Require valid port number for service in 
configuration!\n"));
+      return GNUNET_SYSERR;
+    }
+  }
+  if (0 == port)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, plugin->name,
+                     "Starting in listen only mode\n");
+    return -1; /* listen only */
+  }
+
+
+  if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO"))
+  {
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_CONFIGURATION_get_value_string (cfg, serviceName,
+                                                         "BINDTO", &hostname));
+  }
+  else
+    hostname = NULL;
+
+  if (hostname != NULL)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                     "Resolving `%s' since that is where `%s' will bind to.\n",
+                     hostname, serviceName);
+    memset (&hints, 0, sizeof (struct addrinfo));
+    if (disablev6)
+      hints.ai_family = AF_INET;
+    if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
+        (res == NULL))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"),
+                  hostname, gai_strerror (ret));
+      GNUNET_free (hostname);
+      return GNUNET_SYSERR;
+    }
+    next = res;
+    i = 0;
+    while (NULL != (pos = next))
+    {
+      next = pos->ai_next;
+      if ((disablev6) && (pos->ai_family == AF_INET6))
+        continue;
+      i++;
+    }
+    if (0 == i)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _("Failed to find %saddress for `%s'.\n"),
+                  disablev6 ? "IPv4 " : "", hostname);
+      freeaddrinfo (res);
+      GNUNET_free (hostname);
+      return GNUNET_SYSERR;
+    }
+    resi = i;
+    saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
+    saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
+    i = 0;
+    next = res;
+    while (NULL != (pos = next))
+    {
+      next = pos->ai_next;
+      if ((disablev6) && (pos->ai_family == AF_INET6))
+        continue;
+      if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0))
+        continue;               /* not TCP */
+      if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0))
+        continue;               /* huh? */
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                       "Service will bind to `%s'\n", GNUNET_a2s (pos->ai_addr,
+                                                                  
pos->ai_addrlen));
+      if (pos->ai_family == AF_INET)
+      {
+        GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
+        saddrlens[i] = pos->ai_addrlen;
+        saddrs[i] = GNUNET_malloc (saddrlens[i]);
+        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
+        ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
+      }
+      else
+      {
+        GNUNET_assert (pos->ai_family == AF_INET6);
+        GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
+        saddrlens[i] = pos->ai_addrlen;
+        saddrs[i] = GNUNET_malloc (saddrlens[i]);
+        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
+        ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
+      }
+      i++;
+    }
+    GNUNET_free (hostname);
+    freeaddrinfo (res);
+    resi = i;
+  }
+  else
+  {
+    /* will bind against everything, just set port */
+    if (disablev6)
+    {
+      /* V4-only */
+      resi = 1;
+      i = 0;
+      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
+      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
+
+      saddrlens[i] = sizeof (struct sockaddr_in);
+      saddrs[i] = GNUNET_malloc (saddrlens[i]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
+#endif
+      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
+      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
+    }
+    else
+    {
+      /* dual stack */
+      resi = 2;
+      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
+      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
+      i = 0;
+      saddrlens[i] = sizeof (struct sockaddr_in6);
+      saddrs[i] = GNUNET_malloc (saddrlens[i]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
+#endif
+      ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
+      ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
+      i++;
+      saddrlens[i] = sizeof (struct sockaddr_in);
+      saddrs[i] = GNUNET_malloc (saddrlens[i]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
+#endif
+      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
+      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
+    }
+  }
+  *addrs = saddrs;
+  *addr_lens = saddrlens;
+  return resi;
+}
+
+static void
+server_start_report_addresses (struct HTTP_Server_Plugin *plugin)
+{
+  int res = GNUNET_OK;
+  struct sockaddr **addrs;
+  socklen_t *addrlens;
+
+  res = server_get_addresses (plugin,
+                              plugin->name, plugin->env->cfg,
+                              &addrs, &addrlens);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   _("Found %u addresses to report to NAT service\n"), res);
+
+  if (GNUNET_SYSERR == res)
+  {
+    plugin->nat = NULL;
+    return;
+  }
+
+  plugin->nat =
+      GNUNET_NAT_register (plugin->env->cfg, GNUNET_YES, plugin->port,
+                           (unsigned int) res,
+                           (const struct sockaddr **) addrs, addrlens,
+                           &server_nat_port_map_callback, NULL, plugin);
+  while (res > 0)
+  {
+    res--;
+    GNUNET_assert (addrs[res] != NULL);
+    GNUNET_free (addrs[res]);
+  }
+  GNUNET_free_non_null (addrs);
+  GNUNET_free_non_null (addrlens);
+}
+
+
+static void
+server_stop_report_addresses (struct HTTP_Server_Plugin *plugin)
+{
+  /* Stop NAT handle */
+  if (NULL != plugin->nat)
+    GNUNET_NAT_unregister (plugin->nat);
+
+  /* Clean up addresses */
+  struct HttpAddressWrapper *w;
+
+  while (plugin->addr_head != NULL)
+  {
+    w = plugin->addr_head;
+    GNUNET_CONTAINER_DLL_remove (plugin->addr_head, plugin->addr_tail, w);
+    GNUNET_free (w->addr);
+    GNUNET_free (w);
+  }
+}
+
+
 /**
+ * Check if IPv6 supported on this system
+ */
+static int
+server_check_ipv6_support (struct HTTP_Server_Plugin *plugin)
+{
+  struct GNUNET_NETWORK_Handle *desc = NULL;
+  int res = GNUNET_NO;
+
+  /* Probe IPv6 support */
+  desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
+  if (NULL == desc)
+  {
+    if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) ||
+        (errno == EACCES))
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
+    }
+    GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name,
+                     _
+                     ("Disabling IPv6 since it is not supported on this 
system!\n"));
+    res = GNUNET_NO;
+  }
+  else
+  {
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
+    desc = NULL;
+    res = GNUNET_YES;
+  }
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   "Testing IPv6 on this system: %s\n",
+                   (res == GNUNET_YES) ? "successful" : "failed");
+  return res;
+}
+
+
+/**
+ * Function called when the service shuts down.  Unloads our plugins
+ * and cancels pending validations.
+ *
+ * @param cls closure, unused
+ * @param tc task context (unused)
+ */
+static void
+server_notify_external_hostname (void *cls, const struct 
GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct HTTP_Server_Plugin *plugin = cls;
+  struct HttpAddress *eaddr;
+  char *addr;
+  size_t eaddr_len;
+  size_t uri_len;
+
+  plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK;
+
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+
+  GNUNET_asprintf(&addr, "%s://%s", plugin->protocol, 
plugin->external_hostname);
+  uri_len = strlen (addr) + 1;
+  eaddr_len = sizeof (struct HttpAddress) + uri_len;
+  eaddr = GNUNET_malloc (eaddr_len);
+  eaddr->addr_len = htonl (uri_len);
+  eaddr->addr = (void *) &eaddr[1];
+  memcpy (&eaddr->addr, addr, uri_len);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+                   "Notifying transport about external hostname address 
`%s'\n", addr);
+
+  GNUNET_free (addr);
+  plugin->env->notify_address (plugin->env->cls, GNUNET_YES, eaddr, eaddr_len);
+  plugin->ext_addr = eaddr;
+  plugin->ext_addr_len = eaddr_len;
+}
+
+
+static int
+server_configure_plugin (struct HTTP_Server_Plugin *plugin)
+{
+  unsigned long long port;
+  unsigned long long max_connections;
+  char *bind4_address = NULL;
+  char *bind6_address = NULL;
+
+  /* Use IPv4? */
+  if (GNUNET_CONFIGURATION_have_value
+      (plugin->env->cfg, plugin->name, "USE_IPv4"))
+  {
+    plugin->use_ipv4 =
+        GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name,
+                                              "USE_IPv4");
+  }
+  else
+    plugin->use_ipv4 = GNUNET_YES;
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   _("IPv4 support is %s\n"),
+                   (plugin->use_ipv4 == GNUNET_YES) ? "enabled" : "disabled");
+
+  /* Use IPv6? */
+  if (GNUNET_CONFIGURATION_have_value
+      (plugin->env->cfg, plugin->name, "USE_IPv6"))
+  {
+    plugin->use_ipv6 =
+        GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name,
+                                              "USE_IPv6");
+  }
+  else
+    plugin->use_ipv6 = GNUNET_YES;
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   _("IPv6 support is %s\n"),
+                   (plugin->use_ipv6 == GNUNET_YES) ? "enabled" : "disabled");
+
+  if ((plugin->use_ipv4 == GNUNET_NO) && (plugin->use_ipv6 == GNUNET_NO))
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+                     _
+                     ("Neither IPv4 nor IPv6 are enabled! Fix in 
configuration\n"),
+                     plugin->name);
+    return GNUNET_SYSERR;
+  }
+
+  /* Reading port number from config file */
+  if ((GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name,
+                                              "PORT", &port)) || (port > 
65535))
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+                     _("Port is required! Fix in configuration\n"),
+                     plugin->name);
+    return GNUNET_SYSERR;
+  }
+  plugin->port = port;
+
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   _("Using port %u\n"), plugin->port);
+
+  if ((plugin->use_ipv4 == GNUNET_YES) &&
+      (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg,
+                          plugin->name, "BINDTO", &bind4_address)))
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                     "Binding %s plugin to specific IPv4 address: `%s'\n",
+                     plugin->protocol, bind4_address);
+    plugin->server_addr_v4 = GNUNET_malloc (sizeof (struct sockaddr_in));
+    if (1 != inet_pton (AF_INET, bind4_address,
+                        &plugin->server_addr_v4->sin_addr))
+    {
+        GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+                         _
+                         ("Specific IPv4 address `%s' in configuration file is 
invalid!\n"),
+                         bind4_address);
+      GNUNET_free (bind4_address);
+      GNUNET_free (plugin->server_addr_v4);
+      plugin->server_addr_v4 = NULL;
+      return GNUNET_SYSERR;
+    }
+    else
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                         _("Binding to IPv4 address %s\n"), bind4_address);
+      plugin->server_addr_v4->sin_family = AF_INET;
+      plugin->server_addr_v4->sin_port = htons (plugin->port);
+    }
+    GNUNET_free (bind4_address);
+  }
+
+  if ((plugin->use_ipv6 == GNUNET_YES) &&
+      (GNUNET_YES ==
+       GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name,
+                                              "BINDTO6", &bind6_address)))
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                     "Binding %s plugin to specific IPv6 address: `%s'\n",
+                     plugin->protocol, bind6_address);
+    plugin->server_addr_v6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
+    if (1 !=
+        inet_pton (AF_INET6, bind6_address, 
&plugin->server_addr_v6->sin6_addr))
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+                       _
+                       ("Specific IPv6 address `%s' in configuration file is 
invalid!\n"),
+                       bind6_address);
+      GNUNET_free (bind6_address);
+      GNUNET_free (plugin->server_addr_v6);
+      plugin->server_addr_v6 = NULL;
+      return GNUNET_SYSERR;
+    }
+    else
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                         _("Binding to IPv6 address %s\n"), bind6_address);
+      plugin->server_addr_v6->sin6_family = AF_INET6;
+      plugin->server_addr_v6->sin6_port = htons (plugin->port);
+    }
+    GNUNET_free (bind6_address);
+  }
+
+  if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, 
plugin->name,
+                                              "EXTERNAL_HOSTNAME", 
&plugin->external_hostname))
+  {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                       _("Using external hostname `%s'\n"), 
plugin->external_hostname);
+      plugin->notify_ext_task = GNUNET_SCHEDULER_add_now 
(&server_notify_external_hostname, plugin);
+  }
+  else
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                     "No external hostname configured\n");
+
+
+  /* Optional parameters */
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg,
+                      plugin->name,
+                      "MAX_CONNECTIONS", &max_connections))
+    max_connections = 128;
+  plugin->max_connections = max_connections;
+
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                   _("Maximum number of connections is %u\n"),
+                   plugin->max_connections);
+
+  return GNUNET_OK;
+}
+
+
+/**
+ * Exit point from the plugin.
+ */
+void *
+LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
+{
+  struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
+  struct HTTP_Server_Plugin *plugin = api->cls;
+
+  if (GNUNET_SCHEDULER_NO_TASK != plugin->notify_ext_task)
+  {
+      GNUNET_SCHEDULER_cancel (plugin->notify_ext_task);
+      plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+
+  /* Stop to report addresses to transport service */
+  server_stop_report_addresses (plugin);
+
+  /* Clean up */
+  GNUNET_free_non_null (plugin->external_hostname);
+  GNUNET_free_non_null (plugin->server_addr_v4);
+  GNUNET_free_non_null (plugin->server_addr_v6);
+
+
+  GNUNET_free (plugin);
+  GNUNET_free (api);
+  return NULL;
+}
+
+
+/**
  * Entry point for the plugin.
  */
 void *
@@ -275,9 +910,9 @@
 {
   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
   struct GNUNET_TRANSPORT_PluginFunctions *api;
-  struct Plugin *plugin;
+  struct HTTP_Server_Plugin *plugin;
 
-  plugin = GNUNET_malloc (sizeof (struct Plugin));
+  plugin = GNUNET_malloc (sizeof (struct HTTP_Server_Plugin));
   plugin->env = env;
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
@@ -286,22 +921,35 @@
   api->address_pretty_printer = &http_server_plugin_address_pretty_printer;
   api->check_address = &http_server_plugin_address_suggested;
   api->address_to_string = &http_server_plugin_address_to_string;
+
+#if BUILD_HTTPS
+  plugin->name = "transport-https_server";
+  plugin->protocol = "https";
+#else
+  plugin->name = "transport-http_server";
+  plugin->protocol = "http";
+#endif
+
+  /* Configure plugin */
+  if (GNUNET_SYSERR == server_configure_plugin (plugin));
+  {
+      GNUNET_break (0);
+      LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
+      return NULL;
+  }
+  GNUNET_break (0);
+
+  /* Check IPv6 support */
+  if (GNUNET_YES == plugin->use_ipv6)
+    plugin->use_ipv6 = server_check_ipv6_support (plugin);
+
+  /* Report addresses to transport service */
+  server_start_report_addresses (plugin);
+
   return api;
 }
 
 
-/**
- * Exit point from the plugin.
- */
-void *
-LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
-{
-  struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
-  struct Plugin *plugin = api->cls;
 
-  GNUNET_free (plugin);
-  GNUNET_free (api);
-  return NULL;
-}
 
 /* end of plugin_transport_http_server.c */

Modified: gnunet/src/transport/test_transport_api_http_reverse_proxy.conf
===================================================================
--- gnunet/src/transport/test_transport_api_http_reverse_proxy.conf     
2012-08-22 08:13:47 UTC (rev 23353)
+++ gnunet/src/transport/test_transport_api_http_reverse_proxy.conf     
2012-08-22 10:06:18 UTC (rev 23354)
@@ -9,6 +9,10 @@
 [transport-http_server]
 PORT = 12080
 EXTERNAL_HOSTNAME = fulcrum.net.in.tum.de:12080/peer
+USE_IPV4 = YES
+USE_IPV6 = YES
+BINDTO = 127.0.0.1
+BINDTO6 =  ::1
 
 [arm]
 PORT = 12085
@@ -30,7 +34,8 @@
 [transport]
 #DEBUG = YES
 PORT = 12081
-PLUGINS = http_client http_server
+PLUGINS = http_server
+# http_client
 #BINARY = .libs/gnunet-service-transport
 UNIXPATH = /tmp/gnunet-p1-service-transport.sock
 PREFIX = valgrind --leak-check=full




reply via email to

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