*/
struct GSF_LocalClient *lc;
+ /**
+ * Task scheduled to destroy the request.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier kill_task;
+
};
}
+/**
+ * Free the given client request.
+ *
+ * @param cls the client request to free
+ * @param tc task context
+ */
+static void
+client_request_destroy (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct ClientRequest *cr = cls;
+ struct GSF_LocalClient *lc;
+
+ cr->kill_task = GNUNET_SCHEDULER_NO_TASK;
+ lc = cr->lc;
+ GNUNET_CONTAINER_DLL_remove (lc->cr_head,
+ lc->cr_tail,
+ cr);
+ GSF_pending_request_cancel_ (cr->pr);
+ GNUNET_STATISTICS_update (GSF_stats,
+ gettext_noop ("# client searches active"),
+ - 1,
+ GNUNET_NO);
+ GNUNET_free (cr);
+}
+
+
/**
* Handle a reply to a pending request. Also called if a request
* expires (then with data == NULL). The handler may be called
* expiration.
*
* @param cls user-specified closure
+ * @param eval evaluation of the result
* @param pr handle to the original pending request
- * @param expiration when does 'data' expire?
+ * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
+ * @param expiration when does 'data' expire?
+ * @param type type of the block
* @param data response data, NULL on request expiration
* @param data_len number of bytes in data
- * @param more GNUNET_YES if the request remains active (may call
- * this function again), GNUNET_NO if the request is
- * finished (client must not call GSF_pending_request_cancel_)
*/
static void
client_response_handler (void *cls,
+ enum GNUNET_BLOCK_EvaluationResult eval,
struct GSF_PendingRequest *pr,
+ uint32_t reply_anonymity_level,
struct GNUNET_TIME_Absolute expiration,
+ enum GNUNET_BLOCK_Type type,
const void *data,
- size_t data_len,
- int more)
+ size_t data_len)
{
struct ClientRequest *cr = cls;
struct GSF_LocalClient *lc;
{
/* ugh, request 'timed out' -- how can this be? */
GNUNET_break (0);
- GNUNET_assert (GNUNET_NO == more);
+ return;
+ }
+ prd = GSF_pending_request_get_data_ (pr);
+ GNUNET_break (type != GNUNET_BLOCK_TYPE_ANY);
+ if ( (prd->type != type) &&
+ (prd->type != GNUNET_BLOCK_TYPE_ANY) )
+ {
+ GNUNET_break (0);
return;
}
GNUNET_STATISTICS_update (GSF_stats,
gettext_noop ("# replies received for local clients"),
1,
GNUNET_NO);
- prd = GSF_pending_request_get_data_ (pr);
GNUNET_assert (pr == cr->pr);
lc = cr->lc;
msize = sizeof (struct PutMessage) + data_len;
- pm = GNUNET_malloc (msize);
- pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT);
- pm->header.size = htons (msize);
- pm->type = htonl (prd->type);
- pm->expiration = GNUNET_TIME_absolute_hton (expiration);
- memcpy (&pm[1], data, data_len);
- GSF_local_client_transmit_ (lc, &pm->header);
-
- if (GNUNET_NO == more)
- {
- GNUNET_CONTAINER_DLL_remove (lc->cr_head,
- lc->cr_tail,
- cr);
- GNUNET_free (cr);
- }
+ {
+ char buf[msize];
+
+ pm = (struct PutMessage*) buf;
+ pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT);
+ pm->header.size = htons (msize);
+ pm->type = htonl (type);
+ pm->expiration = GNUNET_TIME_absolute_hton (expiration);
+ memcpy (&pm[1], data, data_len);
+ GSF_local_client_transmit_ (lc, &pm->header);
+ }
+#if DEBUG_FS_CLIENT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Queued reply to query `%s' for local client\n",
+ GNUNET_h2s (&prd->query),
+ (unsigned int) prd->type);
+#endif
+ if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST)
+ return;
+ cr->kill_task = GNUNET_SCHEDULER_add_now (&client_request_destroy,
+ cr);
}
sc = (msize - sizeof (struct SearchMessage)) / sizeof (GNUNET_HashCode);
sm = (const struct SearchMessage*) message;
type = ntohl (sm->type);
-#if DEBUG_FS
+#if DEBUG_FS_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received request for `%s' of type %u from local client\n",
GNUNET_h2s (&sm->query),
}
if (cr != NULL)
{
-#if DEBUG_FS
+#if DEBUG_FS_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Have existing request, merging content-seen lists.\n");
#endif
pos->cr_tail,
cr);
GSF_pending_request_cancel_ (cr->pr);
+ GNUNET_STATISTICS_update (GSF_stats,
+ gettext_noop ("# client searches active"),
+ - 1,
+ GNUNET_NO);
+ if (GNUNET_SCHEDULER_NO_TASK != cr->kill_task)
+ GNUNET_SCHEDULER_cancel (cr->kill_task);
GNUNET_free (cr);
}
while (NULL != (res = pos->res_head))