GNUnet  0.11.x
seti_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012-2016, 2020 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_protocols.h"
29 #include "gnunet_seti_service.h"
30 #include "seti.h"
31 
32 
33 #define LOG(kind, ...) GNUNET_log_from (kind, "seti-api", __VA_ARGS__)
34 
35 
40 {
45 
50 
55 
60 
67 
71  int invalid;
72 
77  uint16_t iteration_id;
78 
79 };
80 
81 
86 {
91  uint32_t accept_id;
92 
97  int accepted;
98 };
99 
100 
106 {
112 
116  void *result_cls;
117 
122  struct GNUNET_SETI_Handle *set;
123 
129 
134  uint32_t *request_id_addr;
135 
140 
145 
149  uint32_t request_id;
150 
156 };
157 
158 
163 {
168 
175 
181 
185  void *listen_cls;
186 
191 
196 
200  struct GNUNET_TIME_Relative reconnect_backoff;
201 
202 };
203 
204 
212 static int
213 check_result (void *cls,
214  const struct GNUNET_SETI_ResultMessage *msg)
215 {
216  /* minimum size was already checked, everything else is OK! */
217  return GNUNET_OK;
218 }
219 
220 
227 static void
228 handle_result (void *cls,
229  const struct GNUNET_SETI_ResultMessage *msg)
230 {
231  struct GNUNET_SETI_Handle *set = cls;
233  struct GNUNET_SETI_Element e;
234  enum GNUNET_SETI_Status result_status;
235  int destroy_set;
236 
237  GNUNET_assert (NULL != set->mq);
238  result_status = (enum GNUNET_SETI_Status) ntohs (msg->result_status);
240  "Got result message with status %d\n",
241  result_status);
242  oh = GNUNET_MQ_assoc_get (set->mq,
243  ntohl (msg->request_id));
244  if (NULL == oh)
245  {
246  /* 'oh' can be NULL if we canceled the operation, but the service
247  did not get the cancel message yet. */
249  "Ignoring result from canceled operation\n");
250  return;
251  }
252 
253  switch (result_status)
254  {
257  e.data = &msg[1];
258  e.size = ntohs (msg->header.size)
259  - sizeof(struct GNUNET_SETI_ResultMessage);
260  e.element_type = ntohs (msg->element_type);
261  if (NULL != oh->result_cb)
262  oh->result_cb (oh->result_cls,
263  &e,
265  result_status);
266  return;
269  GNUNET_MQ_assoc_remove (set->mq,
270  ntohl (msg->request_id));
271  GNUNET_CONTAINER_DLL_remove (set->ops_head,
272  set->ops_tail,
273  oh);
274  /* Need to do this calculation _before_ the result callback,
275  as IF the application still has a valid set handle, it
276  may trigger destruction of the set during the callback. */
277  destroy_set = (GNUNET_YES == set->destroy_requested) &&
278  (NULL == set->ops_head);
279  if (NULL != oh->result_cb)
280  {
281  oh->result_cb (oh->result_cls,
282  NULL,
284  result_status);
285  }
286  else
287  {
289  "No callback for final status\n");
290  }
291  if (destroy_set)
292  GNUNET_SETI_destroy (set);
293  GNUNET_free (oh);
294  return;
295  }
296 }
297 
298 
304 static void
306 {
307  struct GNUNET_SETI_Handle *set = oh->set;
308  struct GNUNET_SETI_OperationHandle *h_assoc;
309 
310  if (NULL != oh->conclude_mqm)
312  /* is the operation already commited? */
313  if (NULL != set)
314  {
316  set->ops_tail,
317  oh);
318  h_assoc = GNUNET_MQ_assoc_remove (set->mq,
319  oh->request_id);
320  GNUNET_assert ((NULL == h_assoc) ||
321  (h_assoc == oh));
322  }
323  GNUNET_free (oh);
324 }
325 
326 
334 void
336 {
337  struct GNUNET_SETI_Handle *set = oh->set;
339  struct GNUNET_MQ_Envelope *mqm;
340 
342  "Cancelling SET operation\n");
343  if (NULL != set)
344  {
346  m->request_id = htonl (oh->request_id);
347  GNUNET_MQ_send (set->mq, mqm);
348  }
350  if ((NULL != set) &&
351  (GNUNET_YES == set->destroy_requested) &&
352  (NULL == set->ops_head))
353  {
355  "Destroying set after operation cancel\n");
356  GNUNET_SETI_destroy (set);
357  }
358 }
359 
360 
368 static void
370  enum GNUNET_MQ_Error error)
371 {
372  struct GNUNET_SETI_Handle *set = cls;
373 
375  "Handling client set error %d\n",
376  error);
377  while (NULL != set->ops_head)
378  {
379  if ((NULL != set->ops_head->result_cb) &&
380  (GNUNET_NO == set->destroy_requested))
381  set->ops_head->result_cb (set->ops_head->result_cls,
382  NULL,
383  0,
385  set_operation_destroy (set->ops_head);
386  }
387  set->invalid = GNUNET_YES;
388 }
389 
390 
398 struct GNUNET_SETI_Handle *
400 {
401  struct GNUNET_SETI_Handle *set = GNUNET_new (struct GNUNET_SETI_Handle);
402  struct GNUNET_MQ_MessageHandler mq_handlers[] = {
406  set),
408  };
409  struct GNUNET_MQ_Envelope *mqm;
410  struct GNUNET_SETI_CreateMessage *create_msg;
411 
412  set->cfg = cfg;
413  set->mq = GNUNET_CLIENT_connect (cfg,
414  "seti",
415  mq_handlers,
417  set);
418  if (NULL == set->mq)
419  {
420  GNUNET_free (set);
421  return NULL;
422  }
424  "Creating new intersection set\n");
425  mqm = GNUNET_MQ_msg (create_msg,
427  GNUNET_MQ_send (set->mq,
428  mqm);
429  return set;
430 }
431 
432 
446 int
448  const struct GNUNET_SETI_Element *element,
450  void *cb_cls)
451 {
452  struct GNUNET_MQ_Envelope *mqm;
454 
456  "adding element of type %u to set %p\n",
457  (unsigned int) element->element_type,
458  set);
459  if (GNUNET_YES == set->invalid)
460  {
461  if (NULL != cb)
462  cb (cb_cls);
463  return GNUNET_SYSERR;
464  }
465  mqm = GNUNET_MQ_msg_extra (msg,
466  element->size,
468  msg->element_type = htons (element->element_type);
469  GNUNET_memcpy (&msg[1],
470  element->data,
471  element->size);
473  cb,
474  cb_cls);
475  GNUNET_MQ_send (set->mq,
476  mqm);
477  return GNUNET_OK;
478 }
479 
480 
487 void
489 {
490  /* destroying set while iterator is active is currently
491  not supported; we should expand the API to allow
492  clients to explicitly cancel the iteration! */
493  if ((NULL != set->ops_head) ||
494  (GNUNET_SYSERR == set->destroy_requested))
495  {
497  "Set operations are pending, delaying set destruction\n");
498  set->destroy_requested = GNUNET_YES;
499  return;
500  }
502  "Really destroying set\n");
503  if (NULL != set->mq)
504  {
505  GNUNET_MQ_destroy (set->mq);
506  set->mq = NULL;
507  }
508  GNUNET_free (set);
509 }
510 
511 
526 GNUNET_SETI_prepare (const struct GNUNET_PeerIdentity *other_peer,
527  const struct GNUNET_HashCode *app_id,
528  const struct GNUNET_MessageHeader *context_msg,
529  const struct GNUNET_SETI_Option options[],
531  void *result_cls)
532 {
533  struct GNUNET_MQ_Envelope *mqm;
536 
538  oh->result_cb = result_cb;
539  oh->result_cls = result_cls;
540  mqm = GNUNET_MQ_msg_nested_mh (msg,
542  context_msg);
543  msg->app_id = *app_id;
544  msg->target_peer = *other_peer;
545  for (const struct GNUNET_SETI_Option *opt = options;
546  GNUNET_SETI_OPTION_END != opt->type;
547  opt++)
548  {
549  switch (opt->type)
550  {
552  msg->return_intersection = htonl (GNUNET_YES);
553  break;
554  default:
556  "Option with type %d not recognized\n",
557  (int) opt->type);
558  }
559  }
560  oh->conclude_mqm = mqm;
561  oh->request_id_addr = &msg->request_id;
562  return oh;
563 }
564 
565 
571 static void
572 listen_connect (void *cls);
573 
574 
582 static int
583 check_request (void *cls,
584  const struct GNUNET_SETI_RequestMessage *msg)
585 {
586  const struct GNUNET_MessageHeader *context_msg;
587 
588  if (ntohs (msg->header.size) == sizeof(*msg))
589  return GNUNET_OK; /* no context message is OK */
590  context_msg = GNUNET_MQ_extract_nested_mh (msg);
591  if (NULL == context_msg)
592  {
593  /* malformed context message is NOT ok */
594  GNUNET_break_op (0);
595  return GNUNET_SYSERR;
596  }
597  return GNUNET_OK;
598 }
599 
600 
607 static void
608 handle_request (void *cls,
609  const struct GNUNET_SETI_RequestMessage *msg)
610 {
611  struct GNUNET_SETI_ListenHandle *lh = cls;
612  struct GNUNET_SETI_Request req;
613  const struct GNUNET_MessageHeader *context_msg;
614  struct GNUNET_MQ_Envelope *mqm;
615  struct GNUNET_SETI_RejectMessage *rmsg;
616 
618  "Processing incoming operation request with id %u\n",
619  ntohl (msg->accept_id));
620  /* we got another valid request => reset the backoff */
622  req.accept_id = ntohl (msg->accept_id);
623  req.accepted = GNUNET_NO;
624  context_msg = GNUNET_MQ_extract_nested_mh (msg);
625  /* calling #GNUNET_SETI_accept() in the listen cb will set req->accepted */
626  lh->listen_cb (lh->listen_cls,
627  &msg->peer_id,
628  context_msg,
629  &req);
630  if (GNUNET_YES == req.accepted)
631  return; /* the accept-case is handled in #GNUNET_SETI_accept() */
633  "Rejected request %u\n",
634  ntohl (msg->accept_id));
635  mqm = GNUNET_MQ_msg (rmsg,
637  rmsg->accept_reject_id = msg->accept_id;
638  GNUNET_MQ_send (lh->mq,
639  mqm);
640 }
641 
642 
650 static void
652  enum GNUNET_MQ_Error error)
653 {
654  struct GNUNET_SETI_ListenHandle *lh = cls;
655 
657  "Listener broke down (%d), re-connecting\n",
658  (int) error);
659  GNUNET_MQ_destroy (lh->mq);
660  lh->mq = NULL;
663  lh);
665 }
666 
667 
673 static void
674 listen_connect (void *cls)
675 {
676  struct GNUNET_SETI_ListenHandle *lh = cls;
677  struct GNUNET_MQ_MessageHandler mq_handlers[] = {
681  lh),
683  };
684  struct GNUNET_MQ_Envelope *mqm;
686 
687  lh->reconnect_task = NULL;
688  GNUNET_assert (NULL == lh->mq);
689  lh->mq = GNUNET_CLIENT_connect (lh->cfg,
690  "seti",
691  mq_handlers,
693  lh);
694  if (NULL == lh->mq)
695  return;
697  msg->app_id = lh->app_id;
698  GNUNET_MQ_send (lh->mq,
699  mqm);
700 }
701 
702 
716  const struct GNUNET_HashCode *app_id,
718  void *listen_cls)
719 {
720  struct GNUNET_SETI_ListenHandle *lh;
721 
723  "Starting listener for app %s\n",
724  GNUNET_h2s (app_id));
725  lh = GNUNET_new (struct GNUNET_SETI_ListenHandle);
726  lh->listen_cb = listen_cb;
727  lh->listen_cls = listen_cls;
728  lh->cfg = cfg;
729  lh->app_id = *app_id;
731  listen_connect (lh);
732  if (NULL == lh->mq)
733  {
734  GNUNET_free (lh);
735  return NULL;
736  }
737  return lh;
738 }
739 
740 
746 void
748 {
750  "Canceling listener %s\n",
751  GNUNET_h2s (&lh->app_id));
752  if (NULL != lh->mq)
753  {
754  GNUNET_MQ_destroy (lh->mq);
755  lh->mq = NULL;
756  }
757  if (NULL != lh->reconnect_task)
758  {
760  lh->reconnect_task = NULL;
761  }
762  GNUNET_free (lh);
763 }
764 
765 
781  const struct GNUNET_SETI_Option options[],
783  void *result_cls)
784 {
785  struct GNUNET_MQ_Envelope *mqm;
788 
789  GNUNET_assert (GNUNET_NO == request->accepted);
791  "Client accepts set intersection operation with id %u\n",
792  request->accept_id);
793  request->accepted = GNUNET_YES;
794  mqm = GNUNET_MQ_msg (msg,
796  msg->accept_reject_id = htonl (request->accept_id);
798  oh->result_cb = result_cb;
799  oh->result_cls = result_cls;
800  oh->conclude_mqm = mqm;
801  oh->request_id_addr = &msg->request_id;
802  for (const struct GNUNET_SETI_Option *opt = options;
803  GNUNET_SETI_OPTION_END != opt->type;
804  opt++)
805  {
806  switch (opt->type)
807  {
810  msg->return_intersection = htonl (GNUNET_YES);
811  break;
812  default:
814  "Option with type %d not recognized\n",
815  (int) opt->type);
816  }
817  }
818  return oh;
819 }
820 
821 
835 int
837  struct GNUNET_SETI_Handle *set)
838 {
839  if (NULL != oh->set)
840  {
841  /* Some other set was already committed for this
842  * operation, there is a logic bug in the client of this API */
843  GNUNET_break (0);
844  return GNUNET_OK;
845  }
846  GNUNET_assert (NULL != set);
847  if (GNUNET_YES == set->invalid)
848  return GNUNET_SYSERR;
850  "Client commits to SET\n");
851  GNUNET_assert (NULL != oh->conclude_mqm);
852  oh->set = set;
853  GNUNET_CONTAINER_DLL_insert (set->ops_head,
854  set->ops_tail,
855  oh);
856  oh->request_id = GNUNET_MQ_assoc_add (set->mq,
857  oh);
858  *oh->request_id_addr = htonl (oh->request_id);
859  GNUNET_MQ_send (set->mq,
860  oh->conclude_mqm);
861  oh->conclude_mqm = NULL;
862  oh->request_id_addr = NULL;
863  return GNUNET_OK;
864 }
865 
866 
874 void
876  struct GNUNET_HashCode *ret_hash)
877 {
879 
880  /* It's not guaranteed that the element data is always after the element header,
881  so we need to hash the chunks separately. */
883  &element->size,
884  sizeof(uint16_t));
886  &element->element_type,
887  sizeof(uint16_t));
889  element->data,
890  element->size);
892  ret_hash);
893 }
894 
895 
896 /* end of seti_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: seti.h:134
uint32_t request_id
Id of our set to evaluate, chosen implicitly by the client when it calls GNUNET_SETI_commit().
Definition: seti.h:162
Success, all elements have been sent (and received).
int invalid
Has the set become invalid (e.g.
Definition: seti_api.c:71
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
int GNUNET_SETI_add_element(struct GNUNET_SETI_Handle *set, const struct GNUNET_SETI_Element *element, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Add an element to the given set.
Definition: seti_api.c:447
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: seti.h:191
The other peer refused to do the operation with us, or something went wrong.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
Sent to the service by the client in order to cancel a set operation.
Definition: seti.h:251
uint32_t accept_id
Id of the request, used to identify the request when accepting/rejecting it.
Definition: seti_api.c:91
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1063
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
uint64_t current_size
Current set size.
Definition: seti.h:201
#define GNUNET_MESSAGE_TYPE_SETI_REQUEST
Notify the client of an incoming request from a remote peer.
#define GNUNET_MESSAGE_TYPE_SETI_EVALUATE
Evaluate a set operation.
uint16_t size
Number of bytes in the buffer pointed to by data.
uint32_t GNUNET_MQ_assoc_add(struct GNUNET_MQ_Handle *mq, void *assoc_data)
Associate the assoc_data in mq with a unique request id.
Definition: mq.c:721
int GNUNET_SETI_commit(struct GNUNET_SETI_OperationHandle *oh, struct GNUNET_SETI_Handle *set)
Commit a set to be used with a set operation.
Definition: seti_api.c:836
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETI_RESULT.
Definition: seti.h:196
#define GNUNET_MESSAGE_TYPE_SETI_ACCEPT
Accept an incoming set request.
Option for set operations.
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_SETI_CANCEL
Cancel a set operation.
static void handle_request(void *cls, const struct GNUNET_SETI_RequestMessage *msg)
Handle request message for a listen operation.
Definition: seti_api.c:608
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
Message sent by a listening client to the service to accept performing the operation with the other p...
Definition: seti.h:76
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint32_t accept_reject_id
ID of the incoming request we want to accept.
Definition: seti.h:86
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:483
Message sent by a listening client to the service to reject performing the operation with the other p...
Definition: seti.h:106
static struct GNUNET_HashCode app_id
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void * listen_cls
Closure for listen_cb.
Definition: seti_api.c:185
Context for cumulative hashing.
Definition: crypto_hash.c:468
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t return_intersection
Return the intersection (1), instead of the elements to remove / the delta (0), in NBO...
Definition: seti.h:97
struct GNUNET_SETI_ListenHandle * GNUNET_SETI_listen(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode *app_id, GNUNET_SETI_ListenCallback listen_cb, void *listen_cls)
Wait for set operation requests for the given application id.
Definition: seti_api.c:715
Opaque handle to a listen operation.
Definition: seti_api.c:162
void * result_cls
Closure for result_cb.
Definition: seti_api.c:116
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle for a set operation request from another peer.
Definition: seti_api.c:85
#define GNUNET_MESSAGE_TYPE_SETI_REJECT
Reject a set request.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
Message sent by the client to the service to start listening for incoming requests to perform a certa...
Definition: seti.h:53
uint16_t element_type
Type of the element to add or remove.
Definition: seti.h:236
void(* GNUNET_SETI_ListenCallback)(void *cls, const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_MessageHeader *context_msg, struct GNUNET_SETI_Request *request)
Called when another peer wants to do a set operation with the local peer.
int accepted
Has the request been accepted already? GNUNET_YES/GNUNET_NO.
Definition: seti_api.c:97
static int check_request(void *cls, const struct GNUNET_SETI_RequestMessage *msg)
Check validity of request message for a listen operation.
Definition: seti_api.c:583
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
struct GNUNET_HashCode app_id
application id
Definition: seti.h:68
int destroy_requested
Should the set be destroyed once all operations are gone? GNUNET_SYSERR if GNUNET_SETI_destroy() must...
Definition: seti_api.c:66
struct GNUNET_SETI_OperationHandle * next
Handles are kept in a linked list.
Definition: seti_api.c:144
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Element should be added to the result set of the local peer, i.e.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
Opaque handle to a set.
Definition: seti_api.c:39
uint32_t request_id
ID of the request we want to cancel.
Definition: seti.h:261
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:787
uint32_t request_id
id the result belongs to
Definition: seti.h:206
struct GNUNET_MQ_Envelope * conclude_mqm
Message sent to the server on calling conclude, NULL if conclude has been called. ...
Definition: seti_api.c:128
struct GNUNET_SETI_OperationHandle * GNUNET_SETI_accept(struct GNUNET_SETI_Request *request, const struct GNUNET_SETI_Option options[], GNUNET_SETI_ResultIterator result_cb, void *result_cls)
Accept a request we got via GNUNET_SETI_listen.
Definition: seti_api.c:780
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration handle for the listener, stored here to be able to reconnect transparently on connectio...
Definition: seti_api.c:174
static struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Active HELLO offering to transport service.
void GNUNET_SETI_operation_cancel(struct GNUNET_SETI_OperationHandle *oh)
Cancel the given set operation.
Definition: seti_api.c:335
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_HashCode app_id
Application id.
Definition: seti.h:172
static void handle_client_listener_error(void *cls, enum GNUNET_MQ_Error error)
Our connection with the set service encountered an error, re-initialize with exponential back-off...
Definition: seti_api.c:651
Element stored in a set.
uint32_t accept_reject_id
ID of the incoming request we want to reject.
Definition: seti.h:116
#define LOG(kind,...)
Definition: seti_api.c:33
const void * data
Actual data of the element.
static int result
Global testing status.
struct GNUNET_SETI_Handle * GNUNET_SETI_create(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create an empty set.
Definition: seti_api.c:399
struct GNUNET_SETI_OperationHandle * ops_tail
Linked list of operations on the set.
Definition: seti_api.c:54
#define GNUNET_MESSAGE_TYPE_SETI_RESULT
Handle result message from operation.
A 512-bit hashcode.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
Message handler for a specific message type.
static void set_operation_destroy(struct GNUNET_SETI_OperationHandle *oh)
Destroy the given set operation.
Definition: seti_api.c:305
static void listen_connect(void *cls)
Connect to the set service in order to listen for requests.
Definition: seti_api.c:674
Handle to an operation.
Definition: seti_api.c:105
uint32_t request_id
Request ID to identify responses.
Definition: seti.h:91
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:323
uint32_t * request_id_addr
Address of the request if in the conclude message, used to patch the request id into the message when...
Definition: seti_api.c:134
int return_intersection
Should we return the resulting intersection (ADD) or the elements to remove (DEL)?
Definition: seti_api.c:155
uint32_t request_id
Request ID to identify the operation within the set.
Definition: seti_api.c:149
#define GNUNET_MESSAGE_TYPE_SETI_ADD
Add element to set.
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:509
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: seti.h:139
#define GNUNET_MESSAGE_TYPE_SETI_LISTEN
Listen for operation requests.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
void GNUNET_SETI_element_hash(const struct GNUNET_SETI_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: seti_api.c:875
Element should be delete from the result set of the local peer, i.e.
void(* GNUNET_SETI_ResultIterator)(void *cls, const struct GNUNET_SETI_Element *element, uint64_t current_size, enum GNUNET_SETI_Status status)
Callback for set union operation results.
struct GNUNET_PeerIdentity target_peer
Peer to evaluate the operation with.
Definition: seti.h:167
struct GNUNET_TIME_Relative reconnect_backoff
Time to wait until we try to reconnect on failure.
Definition: seti_api.c:200
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_SETI_Handle * set
Local set used for the operation, NULL if no set has been provided by conclude yet.
Definition: seti_api.c:122
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:84
GNUNET_SETI_Status
Status for the result callback.
uint16_t iteration_id
Both client and service count the number of iterators created so far to match replies with iterators...
Definition: seti_api.c:77
void * GNUNET_MQ_assoc_remove(struct GNUNET_MQ_Handle *mq, uint32_t request_id)
Remove the association for a request_id.
Definition: mq.c:765
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETI_Status in NBO.
Definition: seti.h:212
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
Message sent by the client to the service to ask starting a new set to perform operations with...
Definition: seti.h:39
struct GNUNET_SETI_OperationHandle * ops_head
Linked list of operations on the set.
Definition: seti_api.c:49
GNUNET_SETI_ListenCallback listen_cb
Function to call on a new incoming request, or on error.
Definition: seti_api.c:180
struct GNUNET_SETI_OperationHandle * prev
Handles are kept in a linked list.
Definition: seti_api.c:139
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETI_REQUEST.
Definition: seti.h:128
Return the elements remaining in the intersection (GNUNET_SETI_STATUS_ADD_LOCAL). ...
GNUNET_SETI_ResultIterator result_cb
Function to be called when we have a result, or an error.
Definition: seti_api.c:111
struct GNUNET_MQ_Handle * mq
Message queue for client.
Definition: seti_api.c:44
struct GNUNET_SCHEDULER_Task * reconnect_task
Task for reconnecting when the listener fails.
Definition: seti_api.c:190
uint32_t return_intersection
Return the intersection (1), instead of the elements to remove / the delta (0), in NBO...
Definition: seti.h:178
Header for all communications.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:837
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration, needed when creating (lazy) copies.
Definition: seti_api.c:59
A request for an operation with another client.
Definition: seti.h:123
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static int check_result(void *cls, const struct GNUNET_SETI_ResultMessage *msg)
Check that the given msg is well-formed.
Definition: seti_api.c:213
Message sent by client to service to initiate a set operation as a client (not as listener)...
Definition: seti.h:151
void GNUNET_SETI_listen_cancel(struct GNUNET_SETI_ListenHandle *lh)
Cancel the given listen operation.
Definition: seti_api.c:747
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: seti_api.c:167
static void handle_client_set_error(void *cls, enum GNUNET_MQ_Error error)
We encountered an error communicating with the set service while performing a set operation...
Definition: seti_api.c:369
Message sent by client to the service to add an element to the set.
Definition: seti.h:226
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint16_t element_type
Application-specific element type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:526
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
struct GNUNET_SETI_OperationHandle * GNUNET_SETI_prepare(const struct GNUNET_PeerIdentity *other_peer, const struct GNUNET_HashCode *app_id, const struct GNUNET_MessageHeader *context_msg, const struct GNUNET_SETI_Option options[], GNUNET_SETI_ResultIterator result_cb, void *result_cls)
Prepare a set operation to be evaluated with another peer.
Definition: seti_api.c:526
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: seti.h:217
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_HashCode app_id
Application ID we listen for.
Definition: seti_api.c:195
#define GNUNET_MESSAGE_TYPE_SETI_CREATE
Create a new local set.
void GNUNET_SETI_destroy(struct GNUNET_SETI_Handle *set)
Destroy the set handle if no operations are left, mark the set for destruction otherwise.
Definition: seti_api.c:488
void * GNUNET_MQ_assoc_get(struct GNUNET_MQ_Handle *mq, uint32_t request_id)
Get the data associated with a request_id in a queue.
Definition: mq.c:749
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
static void handle_result(void *cls, const struct GNUNET_SETI_ResultMessage *msg)
Handle result message for a set operation.
Definition: seti_api.c:228