#define _RECEIVE 0
#define _SEND 1
+
+/* Enable output for debbuging URL's of incoming requests */
+#define DEBUG_URL_PARSE GNUNET_NO
+
+
/**
* Encapsulation of all of the state of the plugin.
*/
*/
int session_ended;
+ /**
+ * Are incoming connection established at the moment
+ */
+ int connect_in_progress;
+
/**
* Absolute time when to receive data again
* Used for receive throttling
*/
size_t size;
+ /**
+ * HTTP/S specific overhead
+ */
+ size_t overhead;
+
/**
* Continuation function to call once the transmission buffer
* has again space available. NULL if there is no
struct HTTP_Server_Plugin *plugin = cls;
struct HTTP_Message *msg;
int bytes_sent = 0;
+ char *stat_txt;
GNUNET_assert (plugin != NULL);
GNUNET_assert (session != NULL);
}
if (NULL == session->server_send)
{
+ if (GNUNET_NO == session->connect_in_progress)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, session->plugin->name,
+ "Session %p/connection %p: Sending message with %u bytes to peer `%s' with FAILED\n",
+ session, session->server_send,
+ msgbuf_size, GNUNET_i2s (&session->target));
GNUNET_break (0);
return GNUNET_SYSERR;
+ }
+ }
+ else
+ {
+ if (GNUNET_YES == session->server_send->disconnect)
+ return GNUNET_SYSERR;
}
- if (GNUNET_YES == session->server_send->disconnect)
- return GNUNET_SYSERR;
-
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name,
"Session %p/connection %p: Sending message with %u to peer `%s' with \n",
session, session->server_send,
GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, session->msg_tail, msg);
- server_reschedule (session->plugin, session->server_send->mhd_daemon, GNUNET_YES);
- server_reschedule_session_timeout (session);
+ GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", plugin->protocol);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ stat_txt, msgbuf_size, GNUNET_NO);
+ GNUNET_free (stat_txt);
- /* struct Plugin *plugin = cls; */
+ if (NULL != session->server_send)
+ {
+ server_reschedule (session->plugin,
+ session->server_send->mhd_daemon,
+ GNUNET_YES);
+ server_reschedule_session_timeout (session);
+ }
return bytes_sent;
}
GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg);
if (msg->transmit_cont != NULL)
{
- msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR);
+ msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR,
+ msg->size, msg->pos + msg->overhead);
}
GNUNET_free (msg);
msg = tmp;
/**
* Parse incoming URL for tag and target
*
- * @url incoming url
- * @target where to store the target
- * @tag where to store the tag
+ * @param plugin plugin
+ * @param url incoming url
+ * @param target where to store the target
+ * @param tag where to store the tag
* @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
static int
server_parse_url (struct HTTP_Server_Plugin *plugin, const char * url, struct GNUNET_PeerIdentity * target, uint32_t *tag)
{
- int debug = GNUNET_YES;
-
char * tag_start = NULL;
char * tag_end = NULL;
char * target_start = NULL;
char * separator = NULL;
char hash[plugin->peer_id_length+1];
int hash_length;
+ unsigned long int ctag;
/* URL parsing
* URL is valid if it is in the form [prefix with (multiple) '/'][peerid[103];tag]*/
if (NULL == separator)
{
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
tag_start = separator + 1;
if (strlen (tag_start) == 0)
{
/* No tag after separator */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
- (*tag) = strtoul (tag_start, &tag_end, 10);
- if ((*tag) == 0)
+ ctag = strtoul (tag_start, &tag_end, 10);
+ if (ctag == 0)
{
/* tag == 0 , invalid */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
- if (((*tag) == ULONG_MAX) && (ERANGE == errno))
+ if ((ctag == ULONG_MAX) && (ERANGE == errno))
{
/* out of range: > ULONG_MAX */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
+ if (ctag > UINT32_MAX)
+ {
+ /* out of range: > UINT32_MAX */
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ (*tag) = (uint32_t) ctag;
if (NULL == tag_end)
{
/* no char after tag */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
if (url[strlen(url)] != tag_end[0])
{
/* there are more not converted chars after tag */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
- if (debug)
+ if (DEBUG_URL_PARSE)
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Found tag `%u' in url\n", (*tag));
if (hash_length != plugin->peer_id_length)
{
/* no char after tag */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
memcpy (hash, target_start, hash_length);
if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target->hashPubKey)))
{
/* hash conversion failed */
- if (debug) GNUNET_break (0);
+ if (DEBUG_URL_PARSE) GNUNET_break (0);
return GNUNET_SYSERR;
}
s->server_send = NULL;
s->session_passed = GNUNET_NO;
s->session_ended = GNUNET_NO;
+ s->connect_in_progress = GNUNET_YES;
server_start_session_timeout(s);
GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
}
s->server_send = sc;
if (direction == _RECEIVE)
s->server_recv = sc;
+
+ if ((NULL != s->server_send) && (NULL != s->server_recv))
+ s->connect_in_progress = GNUNET_NO; /* PUT and GET are connected */
+
#if MHD_VERSION >= 0x00090E00
if ((NULL == s->server_recv) || (NULL == s->server_send))
{
struct Session *s = cls;
ssize_t bytes_read = 0;
struct HTTP_Message *msg;
+ char *stat_txt;
GNUNET_assert (NULL != p);
if (GNUNET_NO == server_exist_session (p, s))
{
GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg);
if (NULL != msg->transmit_cont)
- msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK);
+ msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK,
+ msg->size, msg->size + msg->overhead);
GNUNET_free (msg);
}
}
if (0 < bytes_read)
+ {
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name,
"Sent %u bytes to peer `%s' with session %p \n", bytes_read, GNUNET_i2s (&s->target), s);
+ GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", p->protocol);
+ GNUNET_STATISTICS_update (p->env->stats,
+ stat_txt, -bytes_read, GNUNET_NO);
+ GNUNET_free (stat_txt);
+ GNUNET_asprintf (&stat_txt, "# bytes transmitted via %s_server", p->protocol);
+ GNUNET_STATISTICS_update (p->env->stats,
+ stat_txt, bytes_read, GNUNET_NO);
+ GNUNET_free (stat_txt);
+ }
return bytes_read;
}
struct Session *s = cls;
struct GNUNET_ATS_Information atsi[2];
struct GNUNET_TIME_Relative delay;
+ char *stat_txt;
GNUNET_assert (NULL != p);
if (GNUNET_NO == server_exist_session(p, s))
atsi[1].value = s->ats_address_network_type;
GNUNET_break (s->ats_address_network_type != ntohl (GNUNET_ATS_NET_UNSPECIFIED));
+
delay = plugin->env->receive (plugin->env->cls,
&s->target,
message,
(const struct GNUNET_ATS_Information *) &atsi, 2,
s, s->addr, s->addrlen);
+
+ GNUNET_asprintf (&stat_txt, "# bytes received via %s_server", plugin->protocol);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ stat_txt, ntohs (message->size), GNUNET_NO);
+ GNUNET_free (stat_txt);
+
s->session_passed = GNUNET_YES;
s->next_receive = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay);
if (delay.rel_value > 0)
else
{
response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE), HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO);
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html");
res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response);
MHD_destroy_response (response);
return res;
}
+#define UNSIGNED_MHD_LONG_LONG unsigned MHD_LONG_LONG
+
/**
* Function that queries MHD's select sets and
* starts the task waiting for them.
struct GNUNET_NETWORK_FDSet *wws;
struct GNUNET_NETWORK_FDSet *wes;
int max;
- unsigned MHD_LONG_LONG timeout;
+ UNSIGNED_MHD_LONG_LONG timeout;
static unsigned long long last_timeout = 0;
int haveto;