GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
set_destroy (struct Set *set)
{
/* If the client is not dead yet, destroy it.
- * The client's destroy callback will destroy the set again. */
+ * The client's destroy callback will destroy the set again.
+ * We do this so that the tunnel end handler still has a valid set handle
+ * to destroy. */
if (NULL != set->client)
{
struct GNUNET_SERVER_Client *client = set->client;
GNUNET_SERVER_client_disconnect (client);
return;
}
+ GNUNET_assert (NULL != set->state);
+ set->vt->destroy_set (set->state);
+ set->state = NULL;
if (NULL != set->client_mq)
{
GNUNET_MQ_destroy (set->client_mq);
set->client_mq = NULL;
}
+ if (NULL != set->iter)
+ {
+ GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
+ set->iter = NULL;
+ }
+ GNUNET_CONTAINER_DLL_remove (sets_head, sets_tail, set);
if (NULL != set->elements)
{
GNUNET_CONTAINER_multihashmap_iterate (set->elements,
GNUNET_CONTAINER_multihashmap_destroy (set->elements);
set->elements = NULL;
}
- if (NULL != set->iter)
- {
- GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
- set->iter = NULL;
- }
- GNUNET_assert (NULL != set->state);
- set->vt->destroy_set (set->state);
- set->state = NULL;
- GNUNET_CONTAINER_DLL_remove (sets_head, sets_tail, set);
GNUNET_free (set);
}
const struct GNUNET_MessageHeader *m)
{
struct Set *set;
-
+
set = set_get (client);
if (NULL == set)
{
GNUNET_SERVER_receive_done (client, GNUNET_OK);
msg = (const struct GNUNET_SET_ElementMessage *) m;
el.size = ntohs (m->size) - sizeof *msg;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"client ins/rem element of size %u\n", el.size);
el.data = &msg[1];
if (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (m->type))
&ee->element_hash);
if (NULL != ee_dup)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "element inserted twice, ignoring\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "element inserted twice, ignoring\n");
GNUNET_free (ee);
return;
}
const struct GNUNET_MessageHeader *m)
{
struct Set *set;
-
+
set = set_get (client);
if (NULL == set)
{
incoming->tc = GNUNET_new (struct TunnelContext);;
incoming->tc->vt = &incoming_vt;
incoming->tc->op = (struct OperationState *) incoming;
- incoming->timeout_task =
+ incoming->timeout_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, incoming_timeout_cb, incoming);
GNUNET_CONTAINER_DLL_insert_tail (incoming_head, incoming_tail, incoming);
/**
* Functions with this signature are called whenever a message is
* received.
- *
+ *
* Each time the function must call GNUNET_MESH_receive_done on the tunnel
* in order to receive the next message. This doesn't need to be immediate:
* can be delayed if some processing is done on the message.
* @param tunnel Connection to the other end.
* @param tunnel_ctx Place to store local state associated with the tunnel.
* @param message The actual message.
- *
+ *
* @return GNUNET_OK to keep the tunnel open,
* GNUNET_SYSERR to close it (signal serious error).
*/
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "dispatching mesh message (type: %u)\n",
ntohs (message->type));
- /* FIXME: do this before or after the handler? */
+ /* do this before the handler, as the handler might kill the tunnel */
GNUNET_MESH_receive_done (tunnel);
ret = tc->vt->msg_handler (tc->op, message);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handled mesh message (type: %u)\n",