*/
static struct GNUNET_PEERINFO_Handle *peerinfo;
+/**
+ * Set if we are allowed to advertise our hostlist to others.
+ */
+static int advertising;
+
+/**
+ * Buffer for the hostlist address
+ */
+static char *hostlist_uri;
+
+
+
/**
* Context for host processor.
*/
char *data;
};
-/**
- * Set if we are allowed to advertise our hostlist to others.
- */
-static int advertising;
-
-/**
- * Buffer for the hostlist address
- */
-static char *hostlist_uri;
/**
static void
finish_response (struct HostSet *results)
{
- if (response != NULL)
+ if (NULL != response)
MHD_destroy_response (response);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Creating hostlist response with %u bytes\n",
response =
MHD_create_response_from_data (results->size, results->data, MHD_YES,
MHD_NO);
- if ((daemon_handle_v4 == NULL) && (daemon_handle_v6 == NULL))
+ if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6))
{
MHD_destroy_response (response);
response = NULL;
size_t s;
int has_addr;
- if (err_msg != NULL)
+ if (NULL != err_msg)
{
GNUNET_assert (NULL == peer);
pitr = NULL;
err_msg);
return;
}
- if (peer == NULL)
+ if (NULL == peer)
{
pitr = NULL;
finish_response (results);
return;
}
- if (hello == NULL)
+ if (NULL == hello)
return;
has_addr = GNUNET_NO;
GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_has_addr, &has_addr);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Sending 100 CONTINUE reply\n"));
return MHD_YES; /* send 100 continue */
}
- if (*upload_data_size != 0)
+ if (0 != *upload_data_size)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Refusing `%s' request with %llu bytes of upload data\n"),
GNUNET_YES);
return MHD_NO; /* do not support upload data */
}
- if (response == NULL)
+ if (NULL == response)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_
adv_transmit_ready (void *cls, size_t size, void *buf)
{
static uint64_t hostlist_adv_count;
-
size_t transmission_size;
size_t uri_size; /* Including \0 termination! */
struct GNUNET_MessageHeader header;
char *cbuf;
- if (buf == NULL)
+ if (NULL == buf)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Transmission failed, buffer invalid!\n");
if (!advertising)
return;
- if (hostlist_uri == NULL)
+ if (NULL == hostlist_uri)
return;
size = strlen (hostlist_uri) + 1;
if (size + sizeof (struct GNUNET_MessageHeader) >=
/* nothing to do */
}
+
/**
* PEERINFO calls this function to let us know about a possible peer
* that we might want to connect to.
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Peerinfo is notifying us to rebuild our hostlist\n");
- if (err_msg != NULL)
- {
+ if (NULL != err_msg)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Error in communication with PEERINFO service\n"));
- /* return; */
- }
+ _("Error in communication with PEERINFO service: %s\n"),
+ err_msg);
+ if (NULL != pitr)
+ return; /* re-build already in progress ... */
results = GNUNET_malloc (sizeof (struct HostSet));
- GNUNET_assert (peerinfo != NULL);
+ GNUNET_assert (NULL != peerinfo);
pitr =
GNUNET_PEERINFO_iterate (peerinfo, NULL, GNUNET_TIME_UNIT_MINUTES,
&host_processor, results);
}
+
/**
* Function that queries MHD's select sets and
* starts the task waiting for them.
cfg = c;
stats = st;
peerinfo = GNUNET_PEERINFO_connect (cfg);
- if (peerinfo == NULL)
+ if (NULL == peerinfo)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Could not access PEERINFO service. Exiting.\n"));
GNUNET_CONFIGURATION_get_value_number (cfg, "HOSTLIST", "HTTPPORT",
&port))
return GNUNET_SYSERR;
- if ((port == 0) || (port > UINT16_MAX))
+ if ((0 == port) || (port > UINT16_MAX))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Invalid port number %llu. Exiting.\n"), port);
}
else
ip = NULL;
- if (ip != NULL)
+ if (NULL != ip)
{
if (1 == inet_pton (AF_INET, ip, &i4))
{
sa,
MHD_OPTION_END);
- if ((daemon_handle_v6 == NULL) && (daemon_handle_v4 == NULL))
+ if ((NULL == daemon_handle_v6) && (NULL == daemon_handle_v4))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Could not start hostlist HTTP server on port %u\n"),
if (daemon_handle_v6 != NULL)
hostlist_task_v6 = prepare_daemon (daemon_handle_v6);
- notify = GNUNET_PEERINFO_notify (cfg, process_notify, NULL);
+ notify = GNUNET_PEERINFO_notify (cfg, &process_notify, NULL);
return GNUNET_OK;
}
GNUNET_HOSTLIST_server_stop ()
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n");
- if (NULL != notify)
- {
- GNUNET_PEERINFO_notify_cancel (notify);
- notify = NULL;
- }
if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6)
{
GNUNET_SCHEDULER_cancel (hostlist_task_v6);
GNUNET_SCHEDULER_cancel (hostlist_task_v4);
hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK;
}
- if (pitr != NULL)
- {
- GNUNET_PEERINFO_iterate_cancel (pitr);
- pitr = NULL;
- }
if (NULL != daemon_handle_v4)
{
MHD_stop_daemon (daemon_handle_v4);
MHD_stop_daemon (daemon_handle_v6);
daemon_handle_v6 = NULL;
}
- if (response != NULL)
+ if (NULL != response)
{
MHD_destroy_response (response);
response = NULL;
}
- if (peerinfo != NULL)
+ if (NULL != notify)
+ {
+ GNUNET_PEERINFO_notify_cancel (notify);
+ notify = NULL;
+ }
+ if (NULL != pitr)
+ {
+ GNUNET_PEERINFO_iterate_cancel (pitr);
+ pitr = NULL;
+ }
+ if (NULL != peerinfo)
{
GNUNET_PEERINFO_disconnect (peerinfo);
peerinfo = NULL;
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 Christian Grothoff (and other contributing authors)
+ (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
#include "gnunet_time_lib.h"
#include "peerinfo.h"
-#define LOG(kind,...) GNUNET_log_from (kind, "nse-api",__VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "peerinfo-api",__VA_ARGS__)
/**
* Function to call after transmission has succeeded.
*/
void *cont_cls;
+ /**
+ * Number of bytes of the request message (follows after this struct).
+ */
+ size_t size;
+
+};
+
+
+/**
+ * Context for an iteration request.
+ */
+struct GNUNET_PEERINFO_IteratorContext
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_PEERINFO_IteratorContext *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_PEERINFO_IteratorContext *prev;
+
+ /**
+ * Handle to the PEERINFO service.
+ */
+ struct GNUNET_PEERINFO_Handle *h;
+
+ /**
+ * Function to call with the results.
+ */
+ GNUNET_PEERINFO_Processor callback;
+
+ /**
+ * Closure for 'callback'.
+ */
+ void *callback_cls;
+
+ /**
+ * Our entry in the transmission queue.
+ */
+ struct TransmissionQueueEntry *tqe;
+
+ /**
+ * Task responsible for timeout.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
/**
* Timeout for the operation.
*/
struct GNUNET_TIME_Absolute timeout;
/**
- * Number of bytes of the request message (follows after this struct).
+ * Are we now receiving?
*/
- size_t size;
-
+ int in_receive;
};
*/
struct GNUNET_CLIENT_TransmitHandle *th;
+ /**
+ * Head of iterator DLL.
+ */
+ struct GNUNET_PEERINFO_IteratorContext *ic_head;
+
+ /**
+ * Tail of iterator DLL.
+ */
+ struct GNUNET_PEERINFO_IteratorContext *ic_tail;
+
/**
* ID for a reconnect task.
*/
struct GNUNET_PEERINFO_Handle *
GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
- struct GNUNET_PEERINFO_Handle *ret;
+ struct GNUNET_PEERINFO_Handle *h;
- ret = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle));
- ret->client = GNUNET_CLIENT_connect ("peerinfo", cfg);
- ret->cfg = cfg;
- return ret;
+ h = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle));
+ h->client = GNUNET_CLIENT_connect ("peerinfo", cfg);
+ h->cfg = cfg;
+ return h;
}
GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
{
struct TransmissionQueueEntry *tqe;
+ struct GNUNET_PEERINFO_IteratorContext *ic;
+ while (NULL != (ic = h->ic_head))
+ {
+ GNUNET_break (GNUNET_YES == ic->in_receive);
+ ic->in_receive = GNUNET_NO;
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ }
while (NULL != (tqe = h->tq_head))
{
GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe);
tqe->cont (tqe->cont_cls, GNUNET_SYSERR);
GNUNET_free (tqe);
}
- if (h->th != NULL)
+ if (NULL != h->th)
{
GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
h->th = NULL;
static void
reconnect (struct GNUNET_PEERINFO_Handle *h);
+
/**
* Task scheduled to re-try connecting to the peerinfo service.
*
static void
reconnect (struct GNUNET_PEERINFO_Handle *h)
{
- if (h->r_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != h->r_task)
{
GNUNET_SCHEDULER_cancel (h->r_task);
h->r_task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_CLIENT_disconnect (h->client);
h->client = NULL;
}
+ h->in_receive = GNUNET_NO;
h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg);
if (NULL == h->client)
{
size_t ret;
h->th = NULL;
- if (tqe == NULL)
- return 0;
- if (buf == NULL)
+ if (NULL == tqe)
+ return 0; /* request was cancelled in the meantime */
+ if (NULL == buf)
{
+ /* peerinfo service died */
LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
- _("Failed to transmit message to `%s' service.\n"), "PEERINFO");
+ "Failed to transmit message to `%s' service.\n", "PEERINFO");
GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe);
reconnect (h);
- if (tqe->cont != NULL)
+ if (NULL != tqe->cont)
tqe->cont (tqe->cont_cls, GNUNET_SYSERR);
GNUNET_free (tqe);
return 0;
}
ret = tqe->size;
- GNUNET_assert (size >= ret);
- memcpy (buf, &tqe[1], ret);
+ if (size < ret)
+ {
+ /* change in head of queue (i.e. cancel + add), try again */
+ trigger_transmit (h);
+ return 0;
+ }
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Transmitting request of size %u to `%s' service.\n", ret, "PEERINFO");
+ memcpy (buf, &tqe[1], ret);
GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe);
- if (tqe->cont != NULL)
+ if (NULL != tqe->cont)
tqe->cont (tqe->cont_cls, GNUNET_OK);
else
trigger_transmit (h);
struct TransmissionQueueEntry *tqe;
if (NULL == (tqe = h->tq_head))
- return;
- if (h->th != NULL)
- return;
- if (h->in_receive == GNUNET_YES)
- return;
+ return; /* no requests queued */
+ if (NULL != h->th)
+ return; /* request already pending */
+ if (GNUNET_YES == h->in_receive)
+ return; /* still reading replies from last request */
if (NULL == h->client)
{
+ /* disconnected, try to reconnect */
reconnect (h);
return;
}
h->th =
- GNUNET_CLIENT_notify_transmit_ready (h->client, tqe->size,
- GNUNET_TIME_absolute_get_remaining
- (tqe->timeout), GNUNET_YES,
- &do_transmit, h);
+ GNUNET_CLIENT_notify_transmit_ready (h->client, tqe->size,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_YES,
+ &do_transmit, h);
}
GNUNET_i2s (&peer), hs, "HELLO");
tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + hs);
tqe->size = hs;
- tqe->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
memcpy (&tqe[1], hello, hs);
GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe);
trigger_transmit (h);
/**
- * Context for an iteration request.
- */
-struct GNUNET_PEERINFO_IteratorContext
-{
- /**
- * Handle to the PEERINFO service.
- */
- struct GNUNET_PEERINFO_Handle *h;
-
- /**
- * Function to call with the results.
- */
- GNUNET_PEERINFO_Processor callback;
-
- /**
- * Closure for 'callback'.
- */
- void *callback_cls;
-
- /**
- * Our entry in the transmission queue.
- */
- struct TransmissionQueueEntry *tqe;
-
- /**
- * Task responsible for timeout.
- */
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-
- /**
- * Timeout for the operation.
- */
- struct GNUNET_TIME_Absolute timeout;
-
- /**
- * Are we now receiving?
- */
- int in_receive;
-};
-
-
-/**
- * Type of a function to call when we receive a message
- * from the service.
+ * Type of a function to call when we receive a message from the
+ * service. Call the iterator with the result and (if applicable)
+ * continue to receive more messages or trigger processing the next
+ * event (if applicable).
*
* @param cls closure
* @param msg message received, NULL on timeout or fatal error
peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_PEERINFO_IteratorContext *ic = cls;
+ struct GNUNET_PEERINFO_Handle *h = ic->h;
const struct InfoMessage *im;
const struct GNUNET_HELLO_Message *hello;
+ GNUNET_PEERINFO_Processor cb;
+ void *cb_cls;
uint16_t ms;
- ic->h->in_receive = GNUNET_NO;
- if (msg == NULL)
+ h->in_receive = GNUNET_NO;
+ ic->in_receive = GNUNET_NO;
+ cb = ic->callback;
+ cb_cls = ic->callback_cls;
+ if (NULL == msg)
{
- reconnect (ic->h);
- if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (ic->timeout_task);
- if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL,
- _("Failed to receive response from `PEERINFO' service."));
- GNUNET_free (ic);
+ /* peerinfo service died, signal error */
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ reconnect (h);
+ if (NULL != cb)
+ cb (cb_cls, NULL, NULL,
+ _("Failed to receive response from `PEERINFO' service."));
return;
}
- if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END)
+ if (GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END == ntohs (msg->type))
{
+ /* normal end of list of peers, signal end, process next pending request */
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received end of list of peers from `%s' service\n", "PEERINFO");
- trigger_transmit (ic->h);
- if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (ic->timeout_task);
- if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL, NULL);
- GNUNET_free (ic);
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ trigger_transmit (h);
+ if (NULL != cb)
+ cb (cb_cls, NULL, NULL, NULL);
return;
}
ms = ntohs (msg->size);
if ((ms < sizeof (struct InfoMessage)) ||
(ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
{
+ /* malformed message */
GNUNET_break (0);
- reconnect (ic->h);
- if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (ic->timeout_task);
- if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL,
- _("Received invalid message from `PEERINFO' service."));
- GNUNET_free (ic);
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ reconnect (h);
+ if (NULL != cb)
+ cb (cb_cls, NULL, NULL,
+ _("Received invalid message from `PEERINFO' service."));
return;
}
im = (const struct InfoMessage *) msg;
hello = (const struct GNUNET_HELLO_Message *) &im[1];
if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello))
{
+ /* malformed message */
GNUNET_break (0);
- reconnect (ic->h);
- if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (ic->timeout_task);
- if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL,
- _("Received invalid message from `PEERINFO' service."));
- GNUNET_free (ic);
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ reconnect (h);
+ if (NULL != cb)
+ cb (cb_cls, NULL, NULL,
+ _("Received invalid message from `PEERINFO' service."));
return;
}
}
+ /* normal data message */
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received %u bytes of `%s' information about peer `%s' from `%s' service\n",
(hello == NULL) ? 0 : (unsigned int) GNUNET_HELLO_size (hello), "HELLO",
GNUNET_i2s (&im->peer), "PEERINFO");
- ic->h->in_receive = GNUNET_YES;
- if (ic->callback != NULL)
- ic->callback (ic->callback_cls, &im->peer, hello, NULL);
- GNUNET_CLIENT_receive (ic->h->client, &peerinfo_handler, ic,
+ h->in_receive = GNUNET_YES;
+ ic->in_receive = GNUNET_YES;
+ GNUNET_CLIENT_receive (h->client, &peerinfo_handler, ic,
GNUNET_TIME_absolute_get_remaining (ic->timeout));
+ if (NULL != cb)
+ cb (cb_cls, &im->peer, hello, NULL);
}
iterator_start_receive (void *cls, int transmit_success)
{
struct GNUNET_PEERINFO_IteratorContext *ic = cls;
+ struct GNUNET_PEERINFO_Handle *h = ic->h;
+ GNUNET_PEERINFO_Processor cb;
+ void *cb_cls;
+ ic->tqe = NULL;
if (GNUNET_OK != transmit_success)
{
- if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (ic->timeout_task);
- ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- }
- reconnect (ic->h);
- if (ic->callback != NULL)
- ic->callback (ic->callback_cls, NULL, NULL,
- _
- ("Failed to transmit iteration request to `PEERINFO' service"));
- GNUNET_free (ic);
+ cb = ic->callback;
+ cb_cls = ic->callback_cls;
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ reconnect (h);
+ if (NULL != cb)
+ cb (cb_cls, NULL, NULL,
+ _("Failed to transmit iteration request to `PEERINFO' service"));
return;
}
LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n",
"PEERINFO");
- ic->h->in_receive = GNUNET_YES;
+ h->in_receive = GNUNET_YES;
ic->in_receive = GNUNET_YES;
- ic->tqe = NULL;
- GNUNET_CLIENT_receive (ic->h->client, &peerinfo_handler, ic,
+ GNUNET_CLIENT_receive (h->client, &peerinfo_handler, ic,
GNUNET_TIME_absolute_get_remaining (ic->timeout));
}
signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_PEERINFO_IteratorContext *ic = cls;
+ GNUNET_PEERINFO_Processor cb;
+ void *cb_cls;
ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- if (!ic->in_receive)
- GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, ic->h->tq_tail, ic->tqe);
- else
- reconnect (ic->h);
- ic->callback (ic->callback_cls, NULL, NULL,
- _
- ("Timeout transmitting iteration request to `PEERINFO' service."));
- ic->callback = NULL;
- GNUNET_free_non_null (ic->tqe);
- GNUNET_free (ic);
+ cb = ic->callback;
+ cb_cls = ic->callback_cls;
+ GNUNET_PEERINFO_iterate_cancel (ic);
+ if (NULL != cb)
+ cb (cb_cls, NULL, NULL,
+ _("Timeout transmitting iteration request to `PEERINFO' service."));
}
struct GNUNET_PEERINFO_IteratorContext *ic;
struct TransmissionQueueEntry *tqe;
- if (peer == NULL)
+ if (NULL == peer)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Requesting list of peers from PEERINFO service\n");
ic->timeout = GNUNET_TIME_relative_to_absolute (timeout);
ic->timeout_task =
GNUNET_SCHEDULER_add_delayed (timeout, &signal_timeout, ic);
- tqe->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
tqe->cont = &iterator_start_receive;
tqe->cont_cls = ic;
GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe);
+ GNUNET_CONTAINER_DLL_insert (h->ic_head,
+ h->ic_tail,
+ ic);
trigger_transmit (h);
return ic;
}
void
GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic)
{
- if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ struct GNUNET_PEERINFO_Handle *h;
+
+ h = ic->h;
+ GNUNET_CONTAINER_DLL_remove (h->ic_head,
+ h->ic_tail,
+ ic);
+ if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task)
{
GNUNET_SCHEDULER_cancel (ic->timeout_task);
ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
ic->callback = NULL;
if (GNUNET_YES == ic->in_receive)
return; /* need to finish processing */
- GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, ic->h->tq_tail, ic->tqe);
- GNUNET_free (ic->tqe);
+ if (NULL != ic->tqe)
+ {
+ GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, ic->tqe);
+ GNUNET_free (ic->tqe);
+ }
GNUNET_free (ic);
}