+
+/**
+ * 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;
+
+ plugin->notify_ext_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
+
+ GNUNET_asprintf(&plugin->ext_addr, "%s://%s", plugin->protocol, plugin->external_hostname);
+ plugin->ext_addr_len = strlen (plugin->ext_addr) + 1;
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+ "Notifying transport about external hostname address `%s'\n", plugin->ext_addr);
+
+#if BUILD_HTTPS
+ plugin->env->notify_address (plugin->env->cls, GNUNET_YES,
+ plugin->ext_addr, plugin->ext_addr_len,
+ "https_client");
+#else
+ plugin->env->notify_address (plugin->env->cls, GNUNET_YES,
+ plugin->ext_addr, plugin->ext_addr_len,
+ "http_client");
+#endif
+}
+
+
+/**
+ * Configure the plugin
+ *
+ * @param plugin plugin handle
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+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))
+ {
+ char * tmp = NULL;
+ if (NULL != strstr(plugin->external_hostname, "://"))