[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r11278 - gnunet/src/transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r11278 - gnunet/src/transport |
Date: |
Mon, 10 May 2010 12:05:35 +0200 |
Author: wachs
Date: 2010-05-10 12:05:35 +0200 (Mon, 10 May 2010)
New Revision: 11278
Modified:
gnunet/src/transport/plugin_transport_http.c
Log:
Modified: gnunet/src/transport/plugin_transport_http.c
===================================================================
--- gnunet/src/transport/plugin_transport_http.c 2010-05-10 09:18:29 UTC
(rev 11277)
+++ gnunet/src/transport/plugin_transport_http.c 2010-05-10 10:05:35 UTC
(rev 11278)
@@ -32,10 +32,19 @@
#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
#include "plugin_transport.h"
+#include "microhttpd.h"
-#define DEBUG_TEMPLATE GNUNET_NO
+#define DEBUG_HTTP GNUNET_NO
/**
+ * Text of the response sent back after the last bytes of a PUT
+ * request have been received (just to formally obey the HTTP
+ * protocol).
+ */
+#define HTTP_PUT_RESPONSE "Thank you!"
+
+
+/**
* After how long do we expire an address that we
* learned from another peer if it is not reconfirmed
* by anyone?
@@ -125,6 +134,170 @@
};
/**
+ * Daemon for listening for new IPv4 connections.
+ */
+static struct MHD_Daemon *http_daemon_v4;
+
+/**
+ * Daemon for listening for new IPv6connections.
+ */
+static struct MHD_Daemon *http_daemon_v6;
+
+/**
+ * Our primary task for http daemon handling IPv4 connections
+ */
+static GNUNET_SCHEDULER_TaskIdentifier http_task_v4;
+
+/**
+ * Our primary task for http daemon handling IPv6 connections
+ */
+static GNUNET_SCHEDULER_TaskIdentifier http_task_v6;
+
+struct Plugin *plugin;
+
+/**
+ * Check if we are allowed to connect to the given IP.
+ */
+static int
+acceptPolicyCallback (void *cls,
+ const struct sockaddr *addr, socklen_t addr_len)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Incoming connection \n");
+ /* Currently all incoming connections are accepted, so nothing to do here */
+ return MHD_YES;
+}
+
+/**
+ * Process GET or PUT request received via MHD. For
+ * GET, queue response that will send back our pending
+ * messages. For PUT, process incoming data and send
+ * to GNUnet core. In either case, check if a session
+ * already exists and create a new one if not.
+ */
+static int
+accessHandlerCallback (void *cls,
+ struct MHD_Connection *session,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t * upload_data_size, void **httpSessionCache)
+{
+ struct MHD_Response *response;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"HTTP Daemon has an incoming `%s'
request from \n",method);
+
+ /* Find out if session exists, otherwise create one */
+
+ /* Is it a PUT or a GET request */
+ if ( 0 == strcmp (MHD_HTTP_METHOD_PUT, method) )
+ {
+ /* PUT method here */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Got PUT Request with size %u
\n",upload_data_size);
+ //GNUNET_STATISTICS_update( plugin->env->stats , gettext_noop("# PUT
requests"), 1, GNUNET_NO);
+ }
+ if ( 0 == strcmp (MHD_HTTP_METHOD_GET, method) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Got GET Request with size\n");
+ //GNUNET_STATISTICS_update( plugin->env->stats , gettext_noop("# GET
requests"), 1, GNUNET_NO);
+ }
+
+ response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),
+ HTTP_PUT_RESPONSE, MHD_NO, MHD_NO);
+ MHD_queue_response (session, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+
+ return MHD_YES;
+}
+
+/**
+ * Call MHD to process pending requests and then go back
+ * and schedule the next run.
+ */
+static void run_daemon (void *cls, const struct GNUNET_SCHEDULER_TaskContext
*tc);
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ */
+static GNUNET_SCHEDULER_TaskIdentifier
+prepare_daemon (struct MHD_Daemon *daemon_handle)
+{
+ GNUNET_SCHEDULER_TaskIdentifier ret;
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ struct GNUNET_NETWORK_FDSet *wrs;
+ struct GNUNET_NETWORK_FDSet *wws;
+ struct GNUNET_NETWORK_FDSet *wes;
+ int max;
+ unsigned long long timeout;
+ int haveto;
+ struct GNUNET_TIME_Relative tv;
+
+ FD_ZERO(&rs);
+ FD_ZERO(&ws);
+ FD_ZERO(&es);
+ wrs = GNUNET_NETWORK_fdset_create ();
+ wes = GNUNET_NETWORK_fdset_create ();
+ wws = GNUNET_NETWORK_fdset_create ();
+ max = -1;
+ GNUNET_assert (MHD_YES ==
+ MHD_get_fdset (daemon_handle,
+ &rs,
+ &ws,
+ &es,
+ &max));
+ haveto = MHD_get_timeout (daemon_handle, &timeout);
+ if (haveto == MHD_YES)
+ tv.value = (uint64_t) timeout;
+ else
+ tv = GNUNET_TIME_UNIT_FOREVER_REL;
+ GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max);
+ GNUNET_NETWORK_fdset_copy_native (wws, &ws, max);
+ GNUNET_NETWORK_fdset_copy_native (wes, &es, max);
+ ret = GNUNET_SCHEDULER_add_select (plugin->env->sched,
+ GNUNET_SCHEDULER_PRIORITY_HIGH,
+ GNUNET_SCHEDULER_NO_TASK,
+ tv,
+ wrs,
+ wws,
+ &run_daemon,
+ daemon_handle);
+ GNUNET_NETWORK_fdset_destroy (wrs);
+ GNUNET_NETWORK_fdset_destroy (wws);
+ GNUNET_NETWORK_fdset_destroy (wes);
+ return ret;
+}
+
+/**
+ * Call MHD to process pending requests and then go back
+ * and schedule the next run.
+ */
+static void
+run_daemon (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct MHD_Daemon *daemon_handle = cls;
+
+ if (daemon_handle == http_daemon_v4)
+ http_task_v4 = GNUNET_SCHEDULER_NO_TASK;
+
+ if (daemon_handle == http_daemon_v6)
+ http_task_v6 = GNUNET_SCHEDULER_NO_TASK;
+
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
+
+ GNUNET_assert (MHD_YES == MHD_run (daemon_handle));
+ if (daemon_handle == http_daemon_v4)
+ http_task_v4 = prepare_daemon (daemon_handle);
+ if (daemon_handle == http_daemon_v6)
+ http_task_v6 = prepare_daemon (daemon_handle);
+ return;
+}
+
+/**
* Function that can be used by the transport service to transmit
* a message using the plugin.
*
@@ -271,6 +444,31 @@
struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
struct Plugin *plugin = api->cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Unloading http plugin...\n");
+
+ if ( http_task_v4 != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel(plugin->env->sched, http_task_v4);
+ http_task_v4 = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if ( http_task_v6 != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel(plugin->env->sched, http_task_v6);
+ http_task_v6 = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (http_daemon_v4 != NULL)
+ {
+ MHD_stop_daemon (http_daemon_v4);
+ http_daemon_v4 = NULL;
+ }
+ if (http_daemon_v6 != NULL)
+ {
+ MHD_stop_daemon (http_daemon_v6);
+ http_daemon_v6 = NULL;
+ }
+
GNUNET_free (plugin);
GNUNET_free (api);
return NULL;
@@ -285,7 +483,7 @@
{
struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
struct GNUNET_TRANSPORT_PluginFunctions *api;
- struct Plugin *plugin;
+
long long unsigned int port;
plugin = GNUNET_malloc (sizeof (struct Plugin));
@@ -310,12 +508,42 @@
GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
"http",
_
- ("Require valid port number for service `%s' in
configuration!\n"),
+ ("Require valid port number for transport plugin `%s'
in configuration!\n"),
"transport-http");
libgnunet_plugin_transport_http_done (api);
return NULL;
}
+ if ((http_daemon_v4 == NULL) && (http_daemon_v6 == NULL) && (port != 0))
+ {
+ http_daemon_v6 = MHD_start_daemon (MHD_USE_IPv6,
+ port,
+ &acceptPolicyCallback,
+ NULL, &accessHandlerCallback, NULL,
+ MHD_OPTION_CONNECTION_LIMIT,
(unsigned int) 16,
+ MHD_OPTION_PER_IP_CONNECTION_LIMIT,
(unsigned int) 1,
+ MHD_OPTION_CONNECTION_TIMEOUT,
(unsigned int) 16,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT,
(size_t) (16 * 1024),
+ MHD_OPTION_END);
+ http_daemon_v4 = MHD_start_daemon (MHD_NO_FLAG,
+ port,
+ &acceptPolicyCallback,
+ NULL, &accessHandlerCallback, NULL,
+ MHD_OPTION_CONNECTION_LIMIT,
(unsigned int) 16,
+ MHD_OPTION_PER_IP_CONNECTION_LIMIT,
(unsigned int) 1,
+ MHD_OPTION_CONNECTION_TIMEOUT,
(unsigned int) 16,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT,
(size_t) (16 * 1024),
+ MHD_OPTION_END);
+ }
+
+ if (http_daemon_v4 != NULL)
+ http_task_v4 = prepare_daemon (http_daemon_v4);
+ if (http_daemon_v6 != NULL)
+ http_task_v6 = prepare_daemon (http_daemon_v6);
+
+ if ((http_daemon_v4 == NULL) || (http_daemon_v6 != NULL))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD on port %u\n",port);
+
return api;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r11278 - gnunet/src/transport,
gnunet <=