* @param cls the `struct GNUNET_SET_Handle *`
* @param mh the message
*/
- static void
- handle_iter_element (void *cls,
- const struct GNUNET_SET_IterResponseMessage *msg)
+static void
+handle_iter_element (void *cls,
+ const struct GNUNET_SET_IterResponseMessage *msg)
{
struct GNUNET_SET_Handle *set = cls;
GNUNET_SET_ElementIterator iter = set->iterator;
set->iteration_id++;
iter (set->iterator_cls,
NULL);
+
+ if (GNUNET_YES == set->destroy_requested)
+ GNUNET_SET_destroy (set);
}
struct GNUNET_SET_OperationHandle *oh;
struct GNUNET_SET_Element e;
enum GNUNET_SET_Status result_status;
+ int destroy_set;
GNUNET_assert (NULL != set->mq);
result_status = ntohs (msg->result_status);
GNUNET_CONTAINER_DLL_remove (set->ops_head,
set->ops_tail,
oh);
+ /* Need to do this calculation _before_ the result callback,
+ as IF the application still has a valid set handle, it
+ may trigger destruction of the set during the callback. */
+ destroy_set = (GNUNET_YES == set->destroy_requested) &&
+ (NULL == set->ops_head);
if (NULL != oh->result_cb)
{
oh->result_cb (oh->result_cls,
NULL,
+ GNUNET_ntohll (msg->current_size),
result_status);
}
else
LOG (GNUNET_ERROR_TYPE_DEBUG,
"No callback for final status\n");
}
- if ( (GNUNET_YES == set->destroy_requested) &&
- (NULL == set->ops_head) )
+ if (destroy_set)
GNUNET_SET_destroy (set);
GNUNET_free (oh);
return;
if (NULL != oh->result_cb)
oh->result_cb (oh->result_cls,
&e,
+ GNUNET_ntohll (msg->current_size),
result_status);
}
struct GNUNET_SET_Handle *set = cls;
GNUNET_SET_ElementIterator iter = set->iterator;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_ERROR,
"Handling client set error %d\n",
error);
while (NULL != set->ops_head)
if (NULL != set->ops_head->result_cb)
set->ops_head->result_cb (set->ops_head->result_cls,
NULL,
+ 0,
GNUNET_SET_STATUS_FAILURE);
set_operation_destroy (set->ops_head);
}
set->iterator = NULL;
set->iteration_id++;
+ set->invalid = GNUNET_YES;
if (NULL != iter)
iter (set->iterator_cls,
NULL);
- set->invalid = GNUNET_YES;
- if (GNUNET_YES == set->destroy_requested)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Destroying set after operation failure\n");
- GNUNET_SET_destroy (set);
- }
}
enum GNUNET_SET_OperationType op,
const uint32_t *cookie)
{
- GNUNET_MQ_hd_var_size (result,
- GNUNET_MESSAGE_TYPE_SET_RESULT,
- struct GNUNET_SET_ResultMessage);
- GNUNET_MQ_hd_var_size (iter_element,
- GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT,
- struct GNUNET_SET_IterResponseMessage);
- GNUNET_MQ_hd_fixed_size (iter_done,
- GNUNET_MESSAGE_TYPE_SET_ITER_DONE,
- struct GNUNET_MessageHeader);
- GNUNET_MQ_hd_fixed_size (copy_lazy,
- GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE,
- struct GNUNET_SET_CopyLazyResponseMessage);
struct GNUNET_SET_Handle *set = GNUNET_new (struct GNUNET_SET_Handle);
struct GNUNET_MQ_MessageHandler mq_handlers[] = {
- make_result_handler (set),
- make_iter_element_handler (set),
- make_iter_done_handler (set),
- make_copy_lazy_handler (set),
+ GNUNET_MQ_hd_var_size (result,
+ GNUNET_MESSAGE_TYPE_SET_RESULT,
+ struct GNUNET_SET_ResultMessage,
+ set),
+ GNUNET_MQ_hd_var_size (iter_element,
+ GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT,
+ struct GNUNET_SET_IterResponseMessage,
+ set),
+ GNUNET_MQ_hd_fixed_size (iter_done,
+ GNUNET_MESSAGE_TYPE_SET_ITER_DONE,
+ struct GNUNET_MessageHeader,
+ set),
+ GNUNET_MQ_hd_fixed_size (copy_lazy,
+ GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE,
+ struct GNUNET_SET_CopyLazyResponseMessage,
+ set),
GNUNET_MQ_handler_end ()
};
struct GNUNET_MQ_Envelope *mqm;
struct GNUNET_SET_CopyLazyConnectMessage *copy_msg;
set->cfg = cfg;
- set->mq = GNUNET_CLIENT_connecT (cfg,
+ set->mq = GNUNET_CLIENT_connect (cfg,
"set",
mq_handlers,
&handle_client_set_error,
struct GNUNET_MQ_Envelope *mqm;
struct GNUNET_SET_ElementMessage *msg;
+ LOG (GNUNET_ERROR_TYPE_INFO, "adding element of type %u\n", (unsigned) element->element_type);
+
if (GNUNET_YES == set->invalid)
{
if (NULL != cont)
cont (cont_cls);
return GNUNET_SYSERR;
}
- mqm = GNUNET_MQ_msg_extra (msg, element->size,
+ mqm = GNUNET_MQ_msg_extra (msg,
+ element->size,
GNUNET_MESSAGE_TYPE_SET_ADD);
msg->element_type = htons (element->element_type);
- memcpy (&msg[1],
- element->data,
- element->size);
+ GNUNET_memcpy (&msg[1],
+ element->data,
+ element->size);
GNUNET_MQ_notify_sent (mqm,
cont, cont_cls);
GNUNET_MQ_send (set->mq, mqm);
element->size,
GNUNET_MESSAGE_TYPE_SET_REMOVE);
msg->element_type = htons (element->element_type);
- memcpy (&msg[1],
- element->data,
- element->size);
+ GNUNET_memcpy (&msg[1],
+ element->data,
+ element->size);
GNUNET_MQ_notify_sent (mqm,
cont, cont_cls);
GNUNET_MQ_send (set->mq, mqm);
/* destroying set while iterator is active is currently
not supported; we should expand the API to allow
clients to explicitly cancel the iteration! */
- GNUNET_assert (NULL == set->iterator);
- if (NULL != set->ops_head)
+ if ( (NULL != set->ops_head) || (NULL != set->iterator) )
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Set operations are pending, delaying set destruction\n");
const struct GNUNET_HashCode *app_id,
const struct GNUNET_MessageHeader *context_msg,
enum GNUNET_SET_ResultMode result_mode,
+ struct GNUNET_SET_Option options[],
GNUNET_SET_ResultIterator result_cb,
void *result_cls)
{
struct GNUNET_MQ_Envelope *mqm;
struct GNUNET_SET_OperationHandle *oh;
struct GNUNET_SET_EvaluateMessage *msg;
+ struct GNUNET_SET_Option *opt;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Client prepares set operation (%d)\n",
+ result_mode);
oh = GNUNET_new (struct GNUNET_SET_OperationHandle);
oh->result_cb = result_cb;
oh->result_cls = result_cls;
msg->app_id = *app_id;
msg->result_mode = htonl (result_mode);
msg->target_peer = *other_peer;
+ for (opt = options; opt->type != 0; opt++)
+ {
+ switch (opt->type)
+ {
+ case GNUNET_SET_OPTION_BYZANTINE:
+ msg->byzantine = GNUNET_YES;
+ msg->byzantine_lower_bound = opt->v.num;
+ break;
+ case GNUNET_SET_OPTION_FORCE_FULL:
+ msg->force_full = GNUNET_YES;
+ break;
+ case GNUNET_SET_OPTION_FORCE_DELTA:
+ msg->force_delta = GNUNET_YES;
+ break;
+ default:
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Option with type %d not recognized\n", (int) opt->type);
+ }
+ }
oh->conclude_mqm = mqm;
oh->request_id_addr = &msg->request_id;
{
const struct GNUNET_MessageHeader *context_msg;
+ if (ntohs (msg->header.size) == sizeof (*msg))
+ return GNUNET_OK; /* no context message is OK */
context_msg = GNUNET_MQ_extract_nested_mh (msg);
if (NULL == context_msg)
{
+ /* malformed context message is NOT ok */
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
static void
listen_connect (void *cls)
{
- GNUNET_MQ_hd_var_size (request,
- GNUNET_MESSAGE_TYPE_SET_REQUEST,
- struct GNUNET_SET_RequestMessage);
struct GNUNET_SET_ListenHandle *lh = cls;
struct GNUNET_MQ_MessageHandler mq_handlers[] = {
- make_request_handler (lh),
+ GNUNET_MQ_hd_var_size (request,
+ GNUNET_MESSAGE_TYPE_SET_REQUEST,
+ struct GNUNET_SET_RequestMessage,
+ lh),
GNUNET_MQ_handler_end ()
};
struct GNUNET_MQ_Envelope *mqm;
lh->reconnect_task = NULL;
GNUNET_assert (NULL == lh->mq);
- lh->mq = GNUNET_CLIENT_connecT (lh->cfg,
+ lh->mq = GNUNET_CLIENT_connect (lh->cfg,
"set",
mq_handlers,
&handle_client_listener_error,
struct GNUNET_SET_OperationHandle *
GNUNET_SET_accept (struct GNUNET_SET_Request *request,
enum GNUNET_SET_ResultMode result_mode,
+ struct GNUNET_SET_Option options[],
GNUNET_SET_ResultIterator result_cb,
void *result_cls)
{
struct GNUNET_SET_AcceptMessage *msg;
GNUNET_assert (GNUNET_NO == request->accepted);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Client accepts set operation (%d)\n",
+ result_mode);
request->accepted = GNUNET_YES;
mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_ACCEPT);
msg->accept_reject_id = htonl (request->accept_id);
}
if (GNUNET_YES == set->invalid)
return GNUNET_SYSERR;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Client commits to SET\n");
GNUNET_assert (NULL != oh->conclude_mqm);
oh->set = set;
GNUNET_CONTAINER_DLL_insert (set->ops_head,
set->ops_tail,
oh);
- oh->request_id = GNUNET_MQ_assoc_add (set->mq, oh);
+ oh->request_id = GNUNET_MQ_assoc_add (set->mq,
+ oh);
*oh->request_id_addr = htonl (oh->request_id);
- GNUNET_MQ_send (set->mq, oh->conclude_mqm);
+ GNUNET_MQ_send (set->mq,
+ oh->conclude_mqm);
oh->conclude_mqm = NULL;
oh->request_id_addr = NULL;
return GNUNET_OK;
copy->size = element->size;
copy->element_type = element->element_type;
copy->data = ©[1];
- memcpy ((void *) copy->data, element->data, copy->size);
-
+ GNUNET_memcpy (©[1],
+ element->data,
+ copy->size);
return copy;
}