GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-set.c File Reference

two-peer set operations More...

#include "gnunet-service-set.h"
#include "gnunet-service-set_union.h"
#include "gnunet-service-set_intersection.h"
#include "gnunet-service-set_protocol.h"
#include "gnunet_statistics_service.h"
Include dependency graph for gnunet-service-set.c:

Go to the source code of this file.

Data Structures

struct  LazyCopyRequest
 Lazy copy requests made by a client. More...
 
struct  Listener
 A listener is inhabited by a client, and waits for evaluation requests from remote peers. More...
 
struct  GarbageContext
 Context for the garbage_collect_cb(). More...
 

Macros

#define INCOMING_CHANNEL_TIMEOUT   GNUNET_TIME_UNIT_MINUTES
 How long do we hold on to an incoming channel if there is no local listener before giving up? More...
 

Functions

static struct Operationget_incoming (uint32_t id)
 Get the incoming socket associated with the given id. More...
 
static void incoming_destroy (struct Operation *op)
 Destroy an incoming request from a remote peer. More...
 
static int garbage_collect_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
 Function invoked to check if an element can be removed from the set's history because it is no longer needed. More...
 
static void collect_generation_garbage (struct Set *set)
 Collect and destroy elements that are not needed anymore, because their lifetime (as determined by their generation) does not overlap with any active set operation. More...
 
static int is_excluded_generation (unsigned int generation, struct GenerationRange *excluded, unsigned int excluded_size)
 Is generation in the range of exclusions? More...
 
static int is_element_of_generation (struct ElementEntry *ee, unsigned int query_generation, struct GenerationRange *excluded, unsigned int excluded_size)
 Is element ee part of the set during query_generation? More...
 
int _GSS_is_element_of_operation (struct ElementEntry *ee, struct Operation *op)
 Is element ee part of the set used by op? More...
 
void _GSS_operation_destroy (struct Operation *op, int gc)
 Destroy the given operation. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
 Callback called when a client connects to the service. More...
 
static int destroy_elements_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over hash map entries to free element entries. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
 Clean up after a client has disconnected. More...
 
static int check_incoming_msg (void *cls, const struct OperationRequestMessage *msg)
 Check a request for a set operation from another peer. More...
 
static void handle_incoming_msg (void *cls, const struct OperationRequestMessage *msg)
 Handle a request for a set operation from another peer. More...
 
static void execute_add (struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
 Add an element to set as specified by msg. More...
 
static void execute_remove (struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
 Remove an element from set as specified by msg. More...
 
static void execute_mutation (struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
 Perform a mutation on a set as specified by the msg. More...
 
static void execute_delayed_mutations (struct Set *set)
 Execute mutations that were delayed on a set because of pending operations. More...
 
static void send_client_element (struct Set *set)
 Send the next element of a set to the set's client. More...
 
static void handle_client_iterate (void *cls, const struct GNUNET_MessageHeader *m)
 Called when a client wants to iterate the elements of a set. More...
 
static void handle_client_create_set (void *cls, const struct GNUNET_SET_CreateMessage *msg)
 Called when a client wants to create a new set. More...
 
static void incoming_timeout_cb (void *cls)
 Timeout happens iff: More...
 
static void * channel_new_cb (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
 Method called whenever another peer has added us to a channel the other peer initiated. More...
 
static void channel_end_cb (void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
 Function called whenever a channel is destroyed. More...
 
void _GSS_operation_destroy2 (struct Operation *op)
 This function probably should not exist and be replaced by inlining more specific logic in the various places where it is called. More...
 
static void channel_window_cb (void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
 Function called whenever an MQ-channel's transmission window size changes. More...
 
static void handle_client_listen (void *cls, const struct GNUNET_SET_ListenMessage *msg)
 Called when a client wants to create a new listener. More...
 
static void handle_client_reject (void *cls, const struct GNUNET_SET_RejectMessage *msg)
 Called when the listening client rejects an operation request by another peer. More...
 
static int check_client_mutation (void *cls, const struct GNUNET_SET_ElementMessage *msg)
 Called when a client wants to add or remove an element to a set it inhabits. More...
 
static void handle_client_mutation (void *cls, const struct GNUNET_SET_ElementMessage *msg)
 Called when a client wants to add or remove an element to a set it inhabits. More...
 
static void advance_generation (struct Set *set)
 Advance the current generation of a set, adding exclusion ranges if necessary. More...
 
static int check_client_evaluate (void *cls, const struct GNUNET_SET_EvaluateMessage *msg)
 Called when a client wants to initiate a set operation with another peer. More...
 
static void handle_client_evaluate (void *cls, const struct GNUNET_SET_EvaluateMessage *msg)
 Called when a client wants to initiate a set operation with another peer. More...
 
static void handle_client_iter_ack (void *cls, const struct GNUNET_SET_IterAckMessage *ack)
 Handle an ack from a client, and send the next element. More...
 
static void handle_client_copy_lazy_prepare (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a request from the client to copy a set. More...
 
static void handle_client_copy_lazy_connect (void *cls, const struct GNUNET_SET_CopyLazyConnectMessage *msg)
 Handle a request from the client to connect to a copy of a set. More...
 
static void handle_client_cancel (void *cls, const struct GNUNET_SET_CancelMessage *msg)
 Handle a request from the client to cancel a running set operation. More...
 
static void handle_client_accept (void *cls, const struct GNUNET_SET_AcceptMessage *msg)
 Handle a request from the client to accept a set operation that came from a remote peer. More...
 
static void shutdown_task (void *cls)
 Called to clean up, after a shutdown has been requested. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
 Function called by the service's run method to run service-specific setup code. More...
 
 GNUNET_SERVICE_MAIN ("set", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_accept, GNUNET_MESSAGE_TYPE_SET_ACCEPT, struct GNUNET_SET_AcceptMessage, NULL), GNUNET_MQ_hd_fixed_size(client_iter_ack, GNUNET_MESSAGE_TYPE_SET_ITER_ACK, struct GNUNET_SET_IterAckMessage, NULL), GNUNET_MQ_hd_var_size(client_mutation, GNUNET_MESSAGE_TYPE_SET_ADD, struct GNUNET_SET_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_create_set, GNUNET_MESSAGE_TYPE_SET_CREATE, struct GNUNET_SET_CreateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_iterate, GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_var_size(client_evaluate, GNUNET_MESSAGE_TYPE_SET_EVALUATE, struct GNUNET_SET_EvaluateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_listen, GNUNET_MESSAGE_TYPE_SET_LISTEN, struct GNUNET_SET_ListenMessage, NULL), GNUNET_MQ_hd_fixed_size(client_reject, GNUNET_MESSAGE_TYPE_SET_REJECT, struct GNUNET_SET_RejectMessage, NULL), GNUNET_MQ_hd_var_size(client_mutation, GNUNET_MESSAGE_TYPE_SET_REMOVE, struct GNUNET_SET_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_cancel, GNUNET_MESSAGE_TYPE_SET_CANCEL, struct GNUNET_SET_CancelMessage, NULL), GNUNET_MQ_hd_fixed_size(client_copy_lazy_prepare, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(client_copy_lazy_connect, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT, struct GNUNET_SET_CopyLazyConnectMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static struct GNUNET_CADET_Handlecadet
 Handle to the cadet service, used to listen for and connect to remote peers. More...
 
static struct LazyCopyRequestlazy_copy_head
 DLL of lazy copy requests by this client. More...
 
static struct LazyCopyRequestlazy_copy_tail
 DLL of lazy copy requests by this client. More...
 
static uint32_t lazy_copy_cookie
 Generator for unique cookie we set per lazy copy request. More...
 
struct GNUNET_STATISTICS_Handle_GSS_statistics
 Statistics handle. More...
 
static struct Listenerlistener_head
 Listeners are held in a doubly linked list. More...
 
static struct Listenerlistener_tail
 Listeners are held in a doubly linked list. More...
 
static unsigned int num_clients
 Number of active clients. More...
 
static int in_shutdown
 Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET. More...
 
static uint32_t suggest_id
 Counter for allocating unique IDs for clients, used to identify incoming operation requests from remote peers, that the client can choose to accept or refuse. More...
 

Detailed Description

two-peer set operations

Author
Florian Dold
Christian Grothoff

Definition in file gnunet-service-set.c.

Macro Definition Documentation

◆ INCOMING_CHANNEL_TIMEOUT

#define INCOMING_CHANNEL_TIMEOUT   GNUNET_TIME_UNIT_MINUTES

How long do we hold on to an incoming channel if there is no local listener before giving up?

Definition at line 36 of file gnunet-service-set.c.

Referenced by channel_new_cb().

Function Documentation

◆ get_incoming()

static struct Operation* get_incoming ( uint32_t  id)
static

Get the incoming socket associated with the given id.

Parameters
listenerthe listener to look in
idid to look for
Returns
the incoming socket associated with the id, or NULL if there is none

Definition at line 185 of file gnunet-service-set.c.

References Operation::listener, GNUNET_ARM_Operation::next, Listener::next, op, and Listener::op_head.

Referenced by handle_client_accept(), and handle_client_reject().

186 {
187  for (struct Listener *listener = listener_head; NULL != listener;
188  listener = listener->next)
189  {
190  for (struct Operation *op = listener->op_head; NULL != op; op = op->next)
191  if (op->suggest_id == id)
192  return op;
193  }
194  return NULL;
195 }
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
Operation context used to execute a set operation.
struct Listener * next
Listeners are held in a doubly linked list.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct Listener * listener_head
Listeners are held in a doubly linked list.
Here is the caller graph for this function:

◆ incoming_destroy()

static void incoming_destroy ( struct Operation op)
static

Destroy an incoming request from a remote peer.

Parameters
opremote request to destroy

Definition at line 204 of file gnunet-service-set.c.

References _GSS_operation_destroy2(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_cancel(), Operation::listener, Listener::op_head, Listener::op_tail, and Operation::timeout_task.

Referenced by _GSS_operation_destroy2(), client_disconnect_cb(), and incoming_timeout_cb().

205 {
206  struct Listener *listener;
207 
209  "Destroying incoming operation %p\n",
210  op);
211  if (NULL != (listener = op->listener))
212  {
213  GNUNET_CONTAINER_DLL_remove (listener->op_head, listener->op_tail, op);
214  op->listener = NULL;
215  }
216  if (NULL != op->timeout_task)
217  {
219  op->timeout_task = NULL;
220  }
222 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct Listener * listener
Port this operation runs on.
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
#define GNUNET_log(kind,...)
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ garbage_collect_cb()

static int garbage_collect_cb ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Function invoked to check if an element can be removed from the set's history because it is no longer needed.

Parameters
clsthe struct GarbageContext *
keykey of the element in the map
valuethe struct ElementEntry *
Returns
GNUNET_OK (continue to iterate)

Definition at line 257 of file gnunet-service-set.c.

References GNUNET_OK.

Referenced by collect_generation_garbage().

258 {
259  // struct GarbageContext *gc = cls;
260  // struct ElementEntry *ee = value;
261 
262  // if (GNUNET_YES != ee->removed)
263  // return GNUNET_OK;
264  // if ( (gc->max_op_generation < ee->generation_added) ||
265  // (ee->generation_removed > gc->min_op_generation) )
266  // {
267  // GNUNET_assert (GNUNET_YES ==
268  // GNUNET_CONTAINER_multihashmap_remove (gc->map,
269  // key,
270  // ee));
271  // GNUNET_free (ee);
272  // }
273  return GNUNET_OK;
274 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Here is the caller graph for this function:

◆ collect_generation_garbage()

static void collect_generation_garbage ( struct Set set)
static

Collect and destroy elements that are not needed anymore, because their lifetime (as determined by their generation) does not overlap with any active set operation.

Parameters
setset to garbage collect

Definition at line 285 of file gnunet-service-set.c.

References garbage_collect_cb(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_MAX, GNUNET_MIN, GarbageContext::map, GarbageContext::max_op_generation, GarbageContext::min_op_generation, GNUNET_ARM_Operation::next, and op.

Referenced by _GSS_operation_destroy().

286 {
287  struct GarbageContext gc;
288 
289  gc.min_op_generation = UINT_MAX;
290  gc.max_op_generation = 0;
291  for (struct Operation *op = set->ops_head; NULL != op; op = op->next)
292  {
293  gc.min_op_generation =
294  GNUNET_MIN (gc.min_op_generation, op->generation_created);
295  gc.max_op_generation =
296  GNUNET_MAX (gc.max_op_generation, op->generation_created);
297  }
298  gc.map = set->content->elements;
301  &gc);
302 }
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
struct Operation * ops_head
Evaluate operations are held in a linked list.
static int garbage_collect_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function invoked to check if an element can be removed from the set&#39;s history because it is no longer...
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
Operation context used to execute a set operation.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
Context for the garbage_collect_cb().
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
unsigned int min_op_generation
Lowest generation for which an operation is still pending.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_excluded_generation()

static int is_excluded_generation ( unsigned int  generation,
struct GenerationRange excluded,
unsigned int  excluded_size 
)
static

Is generation in the range of exclusions?

Parameters
generationgeneration to query
excludedarray of generations where the element is excluded
excluded_sizelength of the excluded array
Returns
GNUNET_YES if generation is in any of the ranges

Definition at line 314 of file gnunet-service-set.c.

References end, GNUNET_NO, GNUNET_YES, and start.

Referenced by is_element_of_generation().

317 {
318  for (unsigned int i = 0; i < excluded_size; i++)
319  if ((generation >= excluded[i].start) && (generation < excluded[i].end))
320  return GNUNET_YES;
321  return GNUNET_NO;
322 }
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the caller graph for this function:

◆ is_element_of_generation()

static int is_element_of_generation ( struct ElementEntry ee,
unsigned int  query_generation,
struct GenerationRange excluded,
unsigned int  excluded_size 
)
static

Is element ee part of the set during query_generation?

Parameters
eeelement to test
query_generationgeneration to query
excludedarray of generations where the element is excluded
excluded_sizelength of the excluded array
Returns
GNUNET_YES if the element is in the set, GNUNET_NO if not

Definition at line 335 of file gnunet-service-set.c.

References MutationEvent::added, MutationEvent::generation, GNUNET_assert, GNUNET_break, GNUNET_NO, GNUNET_YES, is_excluded_generation(), ElementEntry::mutations, and ElementEntry::mutations_size.

Referenced by _GSS_is_element_of_operation(), execute_add(), execute_remove(), and send_client_element().

339 {
340  struct MutationEvent *mut;
341  int is_present;
342 
343  GNUNET_assert (NULL != ee->mutations);
344  if (GNUNET_YES ==
345  is_excluded_generation (query_generation, excluded, excluded_size))
346  {
347  GNUNET_break (0);
348  return GNUNET_NO;
349  }
350 
351  is_present = GNUNET_NO;
352 
353  /* Could be made faster with binary search, but lists
354  are small, so why bother. */
355  for (unsigned int i = 0; i < ee->mutations_size; i++)
356  {
357  mut = &ee->mutations[i];
358 
359  if (mut->generation > query_generation)
360  {
361  /* The mutation doesn't apply to our generation
362  anymore. We can'b break here, since mutations aren't
363  sorted by generation. */
364  continue;
365  }
366 
367  if (GNUNET_YES ==
368  is_excluded_generation (mut->generation, excluded, excluded_size))
369  {
370  /* The generation is excluded (because it belongs to another
371  fork via a lazy copy) and thus mutations aren't considered
372  for membership testing. */
373  continue;
374  }
375 
376  /* This would be an inconsistency in how we manage mutations. */
377  if ((GNUNET_YES == is_present) && (GNUNET_YES == mut->added))
378  GNUNET_assert (0);
379  /* Likewise. */
380  if ((GNUNET_NO == is_present) && (GNUNET_NO == mut->added))
381  GNUNET_assert (0);
382 
383  is_present = mut->added;
384  }
385 
386  return is_present;
387 }
struct MutationEvent * mutations
If mutations is not NULL, it contains a list of mutations, ordered by increasing generation.
int added
If added is GNUNET_YES, then this is a remove event, otherwise it is an add event.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
static int is_excluded_generation(unsigned int generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is generation in the range of exclusions?
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
MutationEvent gives information about changes to an element (removal / addition) in a set content...
unsigned int generation
First generation affected by this mutation event.
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int mutations_size
Number of elements in the array mutations.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_is_element_of_operation()

int _GSS_is_element_of_operation ( struct ElementEntry ee,
struct Operation op 
)

Is element ee part of the set used by op?

Parameters
eeelement to test
opoperation the defines the set and its generation
Returns
GNUNET_YES if the element is in the set, GNUNET_NO if not

Definition at line 398 of file gnunet-service-set.c.

References Set::excluded_generations, Set::excluded_generations_size, Operation::generation_created, is_element_of_generation(), and Operation::set.

Referenced by filtered_map_initialization(), handle_union_p2p_demand(), handle_union_p2p_offer(), init_key_to_element_iterator(), and initialize_map_unfiltered().

399 {
400  return is_element_of_generation (ee,
401  op->generation_created,
404 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
unsigned int generation_created
Generation in which the operation handle was created.
static int is_element_of_generation(struct ElementEntry *ee, unsigned int query_generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is element ee part of the set during query_generation?
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_operation_destroy()

void _GSS_operation_destroy ( struct Operation op,
int  gc 
)

Destroy the given operation.

Used for any operation where both peers were known and that thus actually had a vt and channel. Must not be used for operations where 'listener' is still set and we do not know the other peer.

Call the implementation-specific cancel function of the operation. Disconnects from the remote peer. Does not disconnect the client, as there may be multiple operations per set.

Parameters
opoperation to destroy
gcGNUNET_YES to perform garbage collection on the set

Definition at line 421 of file gnunet-service-set.c.

References Operation::channel, collect_generation_garbage(), Operation::context_msg, GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_YES, Operation::listener, Operation::set, and Operation::state.

Referenced by _GSS_operation_destroy2(), client_disconnect_cb(), fail_intersection_operation(), fail_union_operation(), handle_client_cancel(), intersection_channel_death(), send_client_done_and_destroy(), and union_channel_death().

422 {
423  struct Set *set = op->set;
424  struct GNUNET_CADET_Channel *channel;
425 
426  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying operation %p\n", op);
427  GNUNET_assert (NULL == op->listener);
428  if (NULL != op->state)
429  {
430  set->vt->cancel (op);
431  op->state = NULL;
432  }
433  if (NULL != set)
434  {
435  GNUNET_CONTAINER_DLL_remove (set->ops_head, set->ops_tail, op);
436  op->set = NULL;
437  }
438  if (NULL != op->context_msg)
439  {
440  GNUNET_free (op->context_msg);
441  op->context_msg = NULL;
442  }
443  if (NULL != (channel = op->channel))
444  {
445  /* This will free op; called conditionally as this helper function
446  is also called from within the channel disconnect handler. */
447  op->channel = NULL;
449  }
450  if ((NULL != set) && (GNUNET_YES == gc))
452  /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
453  * there was a channel end handler that will free 'op' on the call stack. */
454 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
Opaque handle to a channel.
Definition: cadet_api.c:80
struct Listener * listener
Port this operation runs on.
A set that supports a specific operation with other peers.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
static void collect_generation_garbage(struct Set *set)
Collect and destroy elements that are not needed anymore, because their lifetime (as determined by th...
struct OperationState * state
Operation-specific operation state.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:903
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
struct GNUNET_MQ_Handle mq 
)
static

Callback called when a client connects to the service.

Parameters
clsclosure for the service
cthe new client that connected to the service
mqthe message queue used to send messages to the client
Returns
struct ClientState

Definition at line 466 of file gnunet-service-set.c.

References ClientState::client, GNUNET_new, mq, ClientState::mq, and num_clients.

Referenced by run().

469 {
470  struct ClientState *cs;
471 
472  num_clients++;
473  cs = GNUNET_new (struct ClientState);
474  cs->client = c;
475  cs->mq = mq;
476  return cs;
477 }
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static unsigned int num_clients
Number of active clients.
struct GNUNET_SERVICE_Client * client
Client this is about.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Here is the caller graph for this function:

◆ destroy_elements_iterator()

static int destroy_elements_iterator ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator over hash map entries to free element entries.

Parameters
clsclosure
keycurrent key code
valuea struct ElementEntry * to be free'd
Returns
GNUNET_YES (continue to iterate)

Definition at line 489 of file gnunet-service-set.c.

References GNUNET_free, GNUNET_free_non_null, GNUNET_YES, ElementEntry::mutations, and value.

Referenced by client_disconnect_cb().

492 {
493  struct ElementEntry *ee = value;
494 
496  GNUNET_free (ee);
497  return GNUNET_YES;
498 }
struct MutationEvent * mutations
If mutations is not NULL, it contains a list of mutations, ordered by increasing generation.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static char * value
Value of the record to add/remove.
Information about an element element in the set.
#define GNUNET_YES
Definition: gnunet_common.h:77
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  internal_cls 
)
static

Clean up after a client has disconnected.

Parameters
clsclosure, unused
clientthe client to clean up after
internal_clsthe struct ClientState

Definition at line 509 of file gnunet-service-set.c.

References _GSS_operation_destroy(), Operation::client_request_id, destroy_elements_iterator(), SetContent::elements, GNUNET_assert, GNUNET_CADET_close_port(), GNUNET_CADET_disconnect(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_free_non_null, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, in_shutdown, incoming_destroy(), lazy_copy_head, ClientState::listener, LazyCopyRequest::next, PendingMutation::next, num_clients, op, Listener::op_head, Listener::open_port, Operation::peer, SetContent::pending_mutations_head, SetContent::pending_mutations_tail, pm, SetContent::refcount, ClientState::set, PendingMutation::set, and LazyCopyRequest::source_set.

Referenced by run().

512 {
513  struct ClientState *cs = internal_cls;
514  struct Operation *op;
515  struct Listener *listener;
516  struct Set *set;
517 
518  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, cleaning up\n");
519  if (NULL != (set = cs->set))
520  {
521  struct SetContent *content = set->content;
522  struct PendingMutation *pm;
523  struct PendingMutation *pm_current;
524  struct LazyCopyRequest *lcr;
525 
526  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's set\n");
527  /* Destroy pending set operations */
528  while (NULL != set->ops_head)
529  _GSS_operation_destroy (set->ops_head, GNUNET_NO);
530 
531  /* Destroy operation-specific state */
532  GNUNET_assert (NULL != set->state);
533  set->vt->destroy_set (set->state);
534  set->state = NULL;
535 
536  /* Clean up ongoing iterations */
537  if (NULL != set->iter)
538  {
540  set->iter = NULL;
541  set->iteration_id++;
542  }
543 
544  /* discard any pending mutations that reference this set */
545  pm = content->pending_mutations_head;
546  while (NULL != pm)
547  {
548  pm_current = pm;
549  pm = pm->next;
550  if (pm_current->set == set)
551  {
553  content->pending_mutations_tail,
554  pm_current);
555  GNUNET_free (pm_current);
556  }
557  }
558 
559  /* free set content (or at least decrement RC) */
560  set->content = NULL;
561  GNUNET_assert (0 != content->refcount);
562  content->refcount--;
563  if (0 == content->refcount)
564  {
565  GNUNET_assert (NULL != content->elements);
568  NULL);
570  content->elements = NULL;
571  GNUNET_free (content);
572  }
573  GNUNET_free_non_null (set->excluded_generations);
574  set->excluded_generations = NULL;
575 
576  /* remove set from pending copy requests */
577  lcr = lazy_copy_head;
578  while (NULL != lcr)
579  {
580  struct LazyCopyRequest *lcr_current = lcr;
581 
582  lcr = lcr->next;
583  if (lcr_current->source_set == set)
584  {
587  lcr_current);
588  GNUNET_free (lcr_current);
589  }
590  }
591  GNUNET_free (set);
592  }
593 
594  if (NULL != (listener = cs->listener))
595  {
596  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's listener\n");
598  listener->open_port = NULL;
599  while (NULL != (op = listener->op_head))
600  {
602  "Destroying incoming operation `%u' from peer `%s'\n",
603  (unsigned int) op->client_request_id,
604  GNUNET_i2s (&op->peer));
605  incoming_destroy (op);
606  }
608  GNUNET_free (listener);
609  }
610  GNUNET_free (cs);
611  num_clients--;
612  if ((GNUNET_YES == in_shutdown) && (0 == num_clients))
613  {
614  if (NULL != cadet)
615  {
617  cadet = NULL;
618  }
619  }
620 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
struct Set * set
Set, if associated with the client, otherwise NULL.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:841
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
State we keep per client.
struct PendingMutation * pending_mutations_head
Mutations requested by the client that we&#39;re unable to execute right now because we&#39;re iterating over...
unsigned int refcount
Number of references to the content.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
Information about a mutation to apply to a set.
struct PendingMutation * next
Mutations are kept in a DLL.
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
static unsigned int num_clients
Number of active clients.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
A set that supports a specific operation with other peers.
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET...
struct PendingMutation * pending_mutations_tail
Mutations requested by the client that we&#39;re unable to execute right now because we&#39;re iterating over...
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
Operation context used to execute a set operation.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
struct Set * source_set
Which set are we supposed to copy?
static struct LazyCopyRequest * lazy_copy_tail
DLL of lazy copy requests by this client.
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
struct LazyCopyRequest * next
Kept in a DLL.
struct Set * set
Set this mutation is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:874
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
static struct LazyCopyRequest * lazy_copy_head
DLL of lazy copy requests by this client.
Lazy copy requests made by a client.
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
static struct Listener * listener_head
Listeners are held in a doubly linked list.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_incoming_msg()

static int check_incoming_msg ( void *  cls,
const struct OperationRequestMessage msg 
)
static

Check a request for a set operation from another peer.

Parameters
clsthe operation state
msgthe received message
Returns
GNUNET_OK if the channel should be kept alive, GNUNET_SYSERR to destroy the channel

Definition at line 632 of file gnunet-service-set.c.

References GNUNET_break, GNUNET_break_op, GNUNET_MQ_extract_nested_mh, GNUNET_OK, GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE, GNUNET_SYSERR, Operation::listener, op, OperationRequestMessage::operation, Listener::operation, GNUNET_MessageHeader::size, and Operation::suggest_id.

633 {
634  struct Operation *op = cls;
635  struct Listener *listener = op->listener;
636  const struct GNUNET_MessageHeader *nested_context;
637 
638  /* double operation request */
639  if (0 != op->suggest_id)
640  {
641  GNUNET_break_op (0);
642  return GNUNET_SYSERR;
643  }
644  /* This should be equivalent to the previous condition, but can't hurt to check twice */
645  if (NULL == op->listener)
646  {
647  GNUNET_break (0);
648  return GNUNET_SYSERR;
649  }
650  if (listener->operation !=
651  (enum GNUNET_SET_OperationType) ntohl (msg->operation))
652  {
653  GNUNET_break_op (0);
654  return GNUNET_SYSERR;
655  }
656  nested_context = GNUNET_MQ_extract_nested_mh (msg);
657  if ((NULL != nested_context) &&
658  (ntohs (nested_context->size) > GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE))
659  {
660  GNUNET_break_op (0);
661  return GNUNET_SYSERR;
662  }
663  return GNUNET_OK;
664 }
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
enum GNUNET_SET_OperationType operation
The type of the operation.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct Listener * listener
Port this operation runs on.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
GNUNET_SET_OperationType
The operation that a set set supports.
Operation context used to execute a set operation.
#define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
uint32_t operation
Operation to request, values from enum GNUNET_SET_OperationType
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_incoming_msg()

static void handle_incoming_msg ( void *  cls,
const struct OperationRequestMessage msg 
)
static

Handle a request for a set operation from another peer.

Checks if we have a listener waiting for such a request (and in that case initiates asking the listener about accepting the connection). If no listener is waiting, we queue the operation request in hope that a listener shows up soon (before timeout).

This msg is expected as the first and only msg handled through the non-operation bound virtual table, acceptance of this operation replaces our virtual table and subsequent msgs would be routed differently (as we then know what type of operation this is).

Parameters
clsthe operation state
msgthe received message
Returns
GNUNET_OK if the channel should be kept alive, GNUNET_SYSERR to destroy the channel

Definition at line 685 of file gnunet-service-set.c.

References GNUNET_SET_RequestMessage::accept_id, Listener::app_id, Operation::context_msg, Listener::cs, OperationRequestMessage::element_count, env, GNUNET_assert, GNUNET_copy_message(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SET_REQUEST, GNUNET_MQ_extract_nested_mh, GNUNET_MQ_msg_nested_mh, GNUNET_MQ_send(), GNUNET_SCHEDULER_cancel(), Operation::listener, ClientState::mq, op, OperationRequestMessage::operation, Operation::peer, GNUNET_SET_RequestMessage::peer_id, Operation::remote_element_count, suggest_id, Operation::suggest_id, and Operation::timeout_task.

686 {
687  struct Operation *op = cls;
688  struct Listener *listener = op->listener;
689  const struct GNUNET_MessageHeader *nested_context;
690  struct GNUNET_MQ_Envelope *env;
691  struct GNUNET_SET_RequestMessage *cmsg;
692 
693  nested_context = GNUNET_MQ_extract_nested_mh (msg);
694  /* Make a copy of the nested_context (application-specific context
695  information that is opaque to set) so we can pass it to the
696  listener later on */
697  if (NULL != nested_context)
698  op->context_msg = GNUNET_copy_message (nested_context);
699  op->remote_element_count = ntohl (msg->element_count);
700  GNUNET_log (
702  "Received P2P operation request (op %u, port %s) for active listener\n",
703  (uint32_t) ntohl (msg->operation),
704  GNUNET_h2s (&op->listener->app_id));
705  GNUNET_assert (0 == op->suggest_id);
706  if (0 == suggest_id)
707  suggest_id++;
708  op->suggest_id = suggest_id++;
709  GNUNET_assert (NULL != op->timeout_task);
711  op->timeout_task = NULL;
712  env = GNUNET_MQ_msg_nested_mh (cmsg,
714  op->context_msg);
715  GNUNET_log (
717  "Suggesting incoming request with accept id %u to listener %p of client %p\n",
718  op->suggest_id,
719  listener,
720  listener->cs);
721  cmsg->accept_id = htonl (op->suggest_id);
722  cmsg->peer_id = op->peer;
723  GNUNET_MQ_send (listener->cs->mq, env);
724  /* NOTE: GNUNET_CADET_receive_done() will be called in
725  #handle_client_accept() */
726 }
static uint32_t suggest_id
Counter for allocating unique IDs for clients, used to identify incoming operation requests from remo...
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
uint32_t element_count
For Intersection: my element count.
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#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.
A request for an operation with another client.
Definition: set.h:152
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
struct Listener * listener
Port this operation runs on.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Operation context used to execute a set operation.
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: set.h:163
#define GNUNET_MESSAGE_TYPE_SET_REQUEST
Notify the client of a request from a remote peer.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
#define GNUNET_log(kind,...)
uint32_t operation
Operation to request, values from enum GNUNET_SET_OperationType
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: set.h:168
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Header for all communications.
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:353
uint32_t remote_element_count
Remote peers element count.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct ClientState * cs
Client that owns the listener.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:

◆ execute_add()

static void execute_add ( struct Set set,
const struct GNUNET_SET_ElementMessage msg 
)
static

Add an element to set as specified by msg.

Parameters
setset to manipulate
msgmessage specifying the change

Definition at line 736 of file gnunet-service-set.c.

References GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, MutationEvent::generation, GNUNET_array_append, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_ADD, GNUNET_NO, GNUNET_SET_element_hash(), GNUNET_YES, GNUNET_SET_ElementMessage::header, is_element_of_generation(), ElementEntry::mutations, ElementEntry::mutations_size, ElementEntry::remote, GNUNET_SET_Element::size, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by execute_mutation().

737 {
738  struct GNUNET_SET_Element el;
739  struct ElementEntry *ee;
740  struct GNUNET_HashCode hash;
741 
743  el.size = ntohs (msg->header.size) - sizeof(*msg);
744  el.data = &msg[1];
745  el.element_type = ntohs (msg->element_type);
746  GNUNET_SET_element_hash (&el, &hash);
748  if (NULL == ee)
749  {
751  "Client inserts element %s of size %u\n",
752  GNUNET_h2s (&hash),
753  el.size);
754  ee = GNUNET_malloc (el.size + sizeof(*ee));
755  ee->element.size = el.size;
756  GNUNET_memcpy (&ee[1], el.data, el.size);
757  ee->element.data = &ee[1];
758  ee->element.element_type = el.element_type;
759  ee->remote = GNUNET_NO;
760  ee->mutations = NULL;
761  ee->mutations_size = 0;
762  ee->element_hash = hash;
765  set->content->elements,
766  &ee->element_hash,
767  ee,
769  }
770  else if (GNUNET_YES ==
772  set->current_generation,
775  {
777  "Client inserted element %s of size %u twice (ignored)\n",
778  GNUNET_h2s (&hash),
779  el.size);
780 
781  /* same element inserted twice */
782  return;
783  }
784 
785  {
786  struct MutationEvent mut = { .generation = set->current_generation,
787  .added = GNUNET_YES };
789  }
790  set->vt->add (set->state, ee);
791 }
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
#define GNUNET_MESSAGE_TYPE_SET_ADD
Add element to set.
struct MutationEvent * mutations
If mutations is not NULL, it contains a list of mutations, ordered by increasing generation.
struct SetState * state
Implementation-specific state.
Element stored in a set.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:286
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1246
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:291
const void * data
Actual data of the element.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
Information about an element element in the set.
unsigned int current_generation
Current generation, that is, number of previously executed operations and lazy copies on the underlyi...
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
static int is_element_of_generation(struct ElementEntry *ee, unsigned int query_generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is element ee part of the set during query_generation?
A 512-bit hashcode.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
MutationEvent gives information about changes to an element (removal / addition) in a set content...
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned int generation
First generation affected by this mutation event.
#define GNUNET_array_append(arr, size, element)
Append an element to a list (growing the list by one).
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int mutations_size
Number of elements in the array mutations.
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Definition: gnunet-abd.c:51
#define GNUNET_malloc(size)
Wrapper around malloc.
uint16_t element_type
Application-specific element type.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ execute_remove()

static void execute_remove ( struct Set set,
const struct GNUNET_SET_ElementMessage msg 
)
static

Remove an element from set as specified by msg.

Parameters
setset to manipulate
msgmessage specifying the change

Definition at line 801 of file gnunet-service-set.c.

References GNUNET_SET_Element::data, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, MutationEvent::generation, GNUNET_array_append, GNUNET_assert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_REMOVE, GNUNET_NO, GNUNET_SET_element_hash(), GNUNET_SET_ElementMessage::header, is_element_of_generation(), ElementEntry::mutations, ElementEntry::mutations_size, GNUNET_SET_Element::size, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by execute_mutation().

802 {
803  struct GNUNET_SET_Element el;
804  struct ElementEntry *ee;
805  struct GNUNET_HashCode hash;
806 
808  el.size = ntohs (msg->header.size) - sizeof(*msg);
809  el.data = &msg[1];
810  el.element_type = ntohs (msg->element_type);
811  GNUNET_SET_element_hash (&el, &hash);
813  if (NULL == ee)
814  {
815  /* Client tried to remove non-existing element. */
817  "Client removes non-existing element of size %u\n",
818  el.size);
819  return;
820  }
822  set->current_generation,
825  {
826  /* Client tried to remove element twice */
828  "Client removed element of size %u twice (ignored)\n",
829  el.size);
830  return;
831  }
832  else
833  {
834  struct MutationEvent mut = { .generation = set->current_generation,
835  .added = GNUNET_NO };
836 
838  "Client removes element of size %u\n",
839  el.size);
840 
842  }
843  set->vt->remove (set->state, ee);
844 }
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
struct MutationEvent * mutations
If mutations is not NULL, it contains a list of mutations, ordered by increasing generation.
struct SetState * state
Implementation-specific state.
Element stored in a set.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:286
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1246
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:291
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
Information about an element element in the set.
unsigned int current_generation
Current generation, that is, number of previously executed operations and lazy copies on the underlyi...
static int is_element_of_generation(struct ElementEntry *ee, unsigned int query_generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is element ee part of the set during query_generation?
A 512-bit hashcode.
MutationEvent gives information about changes to an element (removal / addition) in a set content...
unsigned int generation
First generation affected by this mutation event.
#define GNUNET_array_append(arr, size, element)
Append an element to a list (growing the list by one).
#define GNUNET_MESSAGE_TYPE_SET_REMOVE
Remove element from set.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
unsigned int mutations_size
Number of elements in the array mutations.
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Definition: gnunet-abd.c:51
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ execute_mutation()

static void execute_mutation ( struct Set set,
const struct GNUNET_SET_ElementMessage msg 
)
static

Perform a mutation on a set as specified by the msg.

Parameters
setthe set to mutate
msgspecification of what to change

Definition at line 854 of file gnunet-service-set.c.

References execute_add(), execute_remove(), GNUNET_break, GNUNET_MESSAGE_TYPE_SET_ADD, GNUNET_MESSAGE_TYPE_SET_REMOVE, GNUNET_SET_ElementMessage::header, and GNUNET_MessageHeader::type.

Referenced by execute_delayed_mutations(), and handle_client_mutation().

855 {
856  switch (ntohs (msg->header.type))
857  {
859  execute_add (set, msg);
860  break;
861 
863  execute_remove (set, msg);
864  break;
865 
866  default:
867  GNUNET_break (0);
868  }
869 }
#define GNUNET_MESSAGE_TYPE_SET_ADD
Add element to set.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:286
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_SET_REMOVE
Remove element from set.
static void execute_add(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Add an element to set as specified by msg.
static void execute_remove(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Remove an element from set as specified by msg.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ execute_delayed_mutations()

static void execute_delayed_mutations ( struct Set set)
static

Execute mutations that were delayed on a set because of pending operations.

Parameters
setthe set to execute mutations on

Definition at line 879 of file gnunet-service-set.c.

References Set::content, execute_mutation(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, SetContent::iterator_count, PendingMutation::msg, SetContent::pending_mutations_head, SetContent::pending_mutations_tail, pm, and PendingMutation::set.

Referenced by send_client_element().

880 {
881  struct PendingMutation *pm;
882 
883  if (0 != set->content->iterator_count)
884  return; /* still cannot do this */
885  while (NULL != (pm = set->content->pending_mutations_head))
886  {
889  pm);
891  "Executing pending mutation on %p.\n",
892  pm->set);
893  execute_mutation (pm->set, pm->msg);
894  GNUNET_free (pm->msg);
895  GNUNET_free (pm);
896  }
897 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct PendingMutation * pending_mutations_head
Mutations requested by the client that we&#39;re unable to execute right now because we&#39;re iterating over...
static void execute_mutation(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Perform a mutation on a set as specified by the msg.
Information about a mutation to apply to a set.
struct PendingMutation * pending_mutations_tail
Mutations requested by the client that we&#39;re unable to execute right now because we&#39;re iterating over...
struct Set * set
Set this mutation is about.
#define GNUNET_log(kind,...)
int iterator_count
Number of concurrently active iterators.
struct GNUNET_SET_ElementMessage * msg
Message that describes the desired mutation.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_client_element()

static void send_client_element ( struct Set set)
static

Send the next element of a set to the set's client.

The next element is given by the set's current hashmap iterator. The set's iterator will be set to NULL if there are no more elements in the set. The caller must ensure that the set's iterator is valid.

The client will acknowledge each received element with a GNUNET_MESSAGE_TYPE_SET_ITER_ACK message. Our handle_client_iter_ack() will then trigger the next transmission. Note that the GNUNET_MESSAGE_TYPE_SET_ITER_DONE is not acknowledged.

Parameters
setset that should send its next element to its client

Definition at line 914 of file gnunet-service-set.c.

References GNUNET_SET_Element::data, ElementEntry::element, GNUNET_SET_Element::element_type, GNUNET_SET_IterResponseMessage::element_type, execute_delayed_mutations(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_CONTAINER_multihashmap_iterator_next(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_ITER_DONE, GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT, GNUNET_MQ_msg_extra, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, is_element_of_generation(), GNUNET_SET_IterResponseMessage::iteration_id, msg, ret, and GNUNET_SET_Element::size.

Referenced by handle_client_iter_ack(), and handle_client_iterate().

915 {
916  int ret;
917  struct ElementEntry *ee;
918  struct GNUNET_MQ_Envelope *ev;
920 
921  GNUNET_assert (NULL != set->iter);
922  do
923  {
925  NULL,
926  (const void **) &ee);
927  if (GNUNET_NO == ret)
928  {
929  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration on %p done.\n", set);
932  set->iter = NULL;
933  set->iteration_id++;
935  set->content->iterator_count--;
937  GNUNET_MQ_send (set->cs->mq, ev);
938  return;
939  }
940  GNUNET_assert (NULL != ee);
941  }
942  while (GNUNET_NO ==
944  set->iter_generation,
948  "Sending iteration element on %p.\n",
949  set);
950  ev = GNUNET_MQ_msg_extra (msg,
951  ee->element.size,
953  GNUNET_memcpy (&msg[1], ee->element.data, ee->element.size);
954  msg->element_type = htons (ee->element.element_type);
955  msg->iteration_id = htons (set->iteration_id);
956  GNUNET_MQ_send (set->cs->mq, ev);
957 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
#define GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT
Element result for the iterating client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void execute_delayed_mutations(struct Set *set)
Execute mutations that were delayed on a set because of pending operations.
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
Set element transmitted by service to client in response to a set iteration request.
Definition: set.h:324
const void * data
Actual data of the element.
#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
Information about an element element in the set.
static int is_element_of_generation(struct ElementEntry *ee, unsigned int query_generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is element ee part of the set during query_generation?
struct GNUNET_CONTAINER_MultiHashMapIterator * iter
Current state of iterating elements for the client.
unsigned int iter_generation
Generation we&#39;re currently iteration over.
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
#define GNUNET_MESSAGE_TYPE_SET_ITER_DONE
Iteration end marker for the client.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
int iterator_count
Number of concurrently active iterators.
struct GNUNET_SET_Element element
The actual element.
uint16_t iteration_id
Each iter is assigned a unique number, so that the client can distinguish iterations.
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:353
struct ClientState * cs
Client that owns the set.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: set.h:341
uint16_t iteration_id
To which set iteration does this reponse belong to? First iteration (per client) has counter zero...
Definition: set.h:335
uint16_t element_type
Application-specific element type.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_client_iterate()

static void handle_client_iterate ( void *  cls,
const struct GNUNET_MessageHeader m 
)
static

Called when a client wants to iterate the elements of a set.

Checks if we have a set associated with the client and if we can right now start an iteration. If all checks out, starts sending the elements of the set to the client.

Parameters
clsclient that sent the message
mmessage sent by the client

Definition at line 970 of file gnunet-service-set.c.

References ClientState::client, GNUNET_break, GNUNET_CONTAINER_multihashmap_iterator_create(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), send_client_element(), and ClientState::set.

971 {
972  struct ClientState *cs = cls;
973  struct Set *set;
974 
975  if (NULL == (set = cs->set))
976  {
977  /* attempt to iterate over a non existing set */
978  GNUNET_break (0);
980  return;
981  }
982  if (NULL != set->iter)
983  {
984  /* Only one concurrent iterate-action allowed per set */
985  GNUNET_break (0);
987  return;
988  }
990  "Iterating set %p in gen %u with %u content elements\n",
991  (void *) set,
992  set->current_generation,
993  GNUNET_CONTAINER_multihashmap_size (set->content->elements));
995  set->content->iterator_count++;
996  set->iter =
997  GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
998  set->iter_generation = set->current_generation;
999  send_client_element (set);
1000 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
static void send_client_element(struct Set *set)
Send the next element of a set to the set&#39;s client.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ handle_client_create_set()

static void handle_client_create_set ( void *  cls,
const struct GNUNET_SET_CreateMessage msg 
)
static

Called when a client wants to create a new set.

This is typically the first request from a client, and includes the type of set operation to be performed.

Parameters
clsclient that sent the message
mmessage sent by the client

Definition at line 1012 of file gnunet-service-set.c.

References _GSS_intersection_vt(), _GSS_union_vt(), ClientState::client, Set::cs, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SET_OPERATION_INTERSECTION, GNUNET_SET_OPERATION_UNION, GNUNET_YES, GNUNET_SET_CreateMessage::operation, and ClientState::set.

1013 {
1014  struct ClientState *cs = cls;
1015  struct Set *set;
1016 
1018  "Client created new set (operation %u)\n",
1019  (uint32_t) ntohl (msg->operation));
1020  if (NULL != cs->set)
1021  {
1022  /* There can only be one set per client */
1023  GNUNET_break (0);
1025  return;
1026  }
1027  set = GNUNET_new (struct Set);
1028  switch (ntohl (msg->operation))
1029  {
1031  set->vt = _GSS_intersection_vt ();
1032  break;
1033 
1035  set->vt = _GSS_union_vt ();
1036  break;
1037 
1038  default:
1039  GNUNET_free (set);
1040  GNUNET_break (0);
1042  return;
1043  }
1044  set->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1045  set->state = set->vt->create ();
1046  if (NULL == set->state)
1047  {
1048  /* initialization failed (i.e. out of memory) */
1049  GNUNET_free (set);
1051  return;
1052  }
1053  set->content = GNUNET_new (struct SetContent);
1054  set->content->refcount = 1;
1055  set->content->elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1056  set->cs = cs;
1057  cs->set = set;
1059 }
struct Set * set
Set, if associated with the client, otherwise NULL.
const struct SetVT * _GSS_intersection_vt(void)
Get the table with implementing functions for set intersection.
State we keep per client.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
uint32_t operation
Operation type, values of enum GNUNET_SET_OperationType
Definition: set.h:50
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
GNUNET_SET_OperationType
The operation that a set set supports.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
struct GNUNET_SERVICE_Client * client
Client this is about.
const struct SetVT * _GSS_union_vt(void)
Get the table with implementing functions for set union.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct ClientState * cs
Client that owns the set.
Set intersection, only return elements that are in both sets.
Set union, return all elements that are in at least one of the sets.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:

◆ incoming_timeout_cb()

static void incoming_timeout_cb ( void *  cls)
static

Timeout happens iff:

Parameters
clschannel context
tccontext information (why was this task triggered now)

Definition at line 1072 of file gnunet-service-set.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, incoming_destroy(), op, and Operation::timeout_task.

Referenced by channel_new_cb().

1073 {
1074  struct Operation *op = cls;
1075 
1076  op->timeout_task = NULL;
1078  "Remote peer's incoming request timed out\n");
1079  incoming_destroy (op);
1080 }
Operation context used to execute a set operation.
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ channel_new_cb()

static void* channel_new_cb ( void *  cls,
struct GNUNET_CADET_Channel channel,
const struct GNUNET_PeerIdentity source 
)
static

Method called whenever another peer has added us to a channel the other peer initiated.

Only called (once) upon reception of data from a channel we listen on.

The channel context represents the operation itself and gets added to a DLL, from where it gets looked up when our local listener client responds to a proposed/suggested operation or connects and associates with this operation.

Parameters
clsclosure
channelnew handle to the channel
sourcepeer that started the channel
Returns
initial channel context for the channel returns NULL on error

Definition at line 1100 of file gnunet-service-set.c.

References Operation::channel, GNUNET_CADET_get_mq(), GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_SCHEDULER_add_delayed(), INCOMING_CHANNEL_TIMEOUT, incoming_timeout_cb(), Operation::listener, Operation::mq, op, Listener::op_head, Listener::op_tail, Operation::peer, Operation::salt, source, and Operation::timeout_task.

Referenced by handle_client_listen().

1103 {
1104  struct Listener *listener = cls;
1105  struct Operation *op;
1106 
1107  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New incoming channel\n");
1108  op = GNUNET_new (struct Operation);
1109  op->listener = listener;
1110  op->peer = *source;
1111  op->channel = channel;
1112  op->mq = GNUNET_CADET_get_mq (op->channel);
1116  op);
1117  GNUNET_CONTAINER_DLL_insert (listener->op_head, listener->op_tail, op);
1118  return op;
1119 }
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define INCOMING_CHANNEL_TIMEOUT
How long do we hold on to an incoming channel if there is no local listener before giving up...
#define GNUNET_new(type)
Allocate a struct or union of the given type.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
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:1253
struct Listener * listener
Port this operation runs on.
Randomness for IVs etc.
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
static void incoming_timeout_cb(void *cls)
Timeout happens iff:
static GstElement * source
Appsrc instance into which we write data for the pipeline.
Operation context used to execute a set operation.
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint32_t salt
Salt to use for the operation.
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ channel_end_cb()

static void channel_end_cb ( void *  channel_ctx,
const struct GNUNET_CADET_Channel channel 
)
static

Function called whenever a channel is destroyed.

Should clean up any associated state. It must NOT call GNUNET_CADET_channel_destroy() on the channel.

The peer_disconnect function is part of a a virtual table set initially either when a peer creates a new channel with us, or once we create a new channel ourselves (evaluate).

Once we know the exact type of operation (union/intersection), the vt is replaced with an operation specific instance (GSS[op]_vt).

Parameters
channel_ctxplace where local state associated with the channel is stored
channelconnection to the other end (henceforth invalid)

Definition at line 1139 of file gnunet-service-set.c.

References _GSS_operation_destroy2(), Operation::channel, and op.

Referenced by handle_client_evaluate(), and handle_client_listen().

1140 {
1141  struct Operation *op = channel_ctx;
1142 
1143  op->channel = NULL;
1145 }
struct GNUNET_CADET_Channel * channel
Channel to the peer.
Operation context used to execute a set operation.
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_operation_destroy2()

void _GSS_operation_destroy2 ( struct Operation op)

This function probably should not exist and be replaced by inlining more specific logic in the various places where it is called.

Definition at line 1154 of file gnunet-service-set.c.

References _GSS_operation_destroy(), Operation::channel, SetVT::channel_death, GNUNET_CADET_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_YES, incoming_destroy(), Operation::listener, Operation::set, and Set::vt.

Referenced by channel_end_cb(), handle_client_reject(), handle_union_p2p_full_done(), incoming_destroy(), and maybe_finish().

1155 {
1156  struct GNUNET_CADET_Channel *channel;
1157 
1158  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "channel_end_cb called\n");
1159  if (NULL != (channel = op->channel))
1160  {
1161  /* This will free op; called conditionally as this helper function
1162  is also called from within the channel disconnect handler. */
1163  op->channel = NULL;
1164  GNUNET_CADET_channel_destroy (channel);
1165  }
1166  if (NULL != op->listener)
1167  {
1168  incoming_destroy (op);
1169  return;
1170  }
1171  if (NULL != op->set)
1172  op->set->vt->channel_death (op);
1173  else
1175  GNUNET_free (op);
1176 }
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_CADET_Channel * channel
Channel to the peer.
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
Opaque handle to a channel.
Definition: cadet_api.c:80
struct Listener * listener
Port this operation runs on.
OpChannelDeathImpl channel_death
Callback called in case the CADET channel died.
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
const struct SetVT * vt
Virtual table for this set.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:903
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ channel_window_cb()

static void channel_window_cb ( void *  cls,
const struct GNUNET_CADET_Channel channel,
int  window_size 
)
static

Function called whenever an MQ-channel's transmission window size changes.

The first callback in an outgoing channel will be with a non-zero value and will mean the channel is connected to the destination.

For an incoming channel it will be called immediately after the GNUNET_CADET_ConnectEventHandler, also with a non-zero value.

Parameters
clsChannel closure.
channelConnection to the other end (henceforth invalid).
window_sizeNew window size. If the is more messages than buffer size this value will be negative..

Definition at line 1194 of file gnunet-service-set.c.

Referenced by handle_client_evaluate(), and handle_client_listen().

1197 {
1198  /* FIXME: not implemented, we could do flow control here... */
1199 }
Here is the caller graph for this function:

◆ handle_client_listen()

static void handle_client_listen ( void *  cls,
const struct GNUNET_SET_ListenMessage msg 
)
static

Called when a client wants to create a new listener.

Parameters
clsclient that sent the message
msgmessage sent by the client

Definition at line 1209 of file gnunet-service-set.c.

References GNUNET_SET_ListenMessage::app_id, Listener::app_id, channel_end_cb(), channel_new_cb(), channel_window_cb(), ClientState::client, Listener::cs, GNUNET_break, GNUNET_CADET_open_port(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), ClientState::listener, Listener::open_port, GNUNET_SET_ListenMessage::operation, and Listener::operation.

1210 {
1211  struct ClientState *cs = cls;
1212  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1213  { GNUNET_MQ_hd_var_size (incoming_msg,
1215  struct OperationRequestMessage,
1216  NULL),
1217  GNUNET_MQ_hd_var_size (union_p2p_ibf,
1219  struct IBFMessage,
1220  NULL),
1221  GNUNET_MQ_hd_var_size (union_p2p_elements,
1224  NULL),
1225  GNUNET_MQ_hd_var_size (union_p2p_offer,
1227  struct GNUNET_MessageHeader,
1228  NULL),
1229  GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1231  struct InquiryMessage,
1232  NULL),
1233  GNUNET_MQ_hd_var_size (union_p2p_demand,
1235  struct GNUNET_MessageHeader,
1236  NULL),
1237  GNUNET_MQ_hd_fixed_size (union_p2p_done,
1239  struct GNUNET_MessageHeader,
1240  NULL),
1241  GNUNET_MQ_hd_fixed_size (union_p2p_over,
1243  struct GNUNET_MessageHeader,
1244  NULL),
1245  GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1247  struct GNUNET_MessageHeader,
1248  NULL),
1249  GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1251  struct GNUNET_MessageHeader,
1252  NULL),
1253  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1255  struct StrataEstimatorMessage,
1256  NULL),
1257  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1259  struct StrataEstimatorMessage,
1260  NULL),
1261  GNUNET_MQ_hd_var_size (union_p2p_full_element,
1264  NULL),
1265  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1268  NULL),
1269  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1271  struct BFMessage,
1272  NULL),
1273  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1275  struct IntersectionDoneMessage,
1276  NULL),
1277  GNUNET_MQ_handler_end () };
1278  struct Listener *listener;
1279 
1280  if (NULL != cs->listener)
1281  {
1282  /* max. one active listener per client! */
1283  GNUNET_break (0);
1285  return;
1286  }
1287  listener = GNUNET_new (struct Listener);
1288  listener->cs = cs;
1289  cs->listener = listener;
1290  listener->app_id = msg->app_id;
1291  listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1294  "New listener created (op %u, port %s)\n",
1295  listener->operation,
1296  GNUNET_h2s (&listener->app_id));
1297  listener->open_port = GNUNET_CADET_open_port (cadet,
1298  &msg->app_id,
1299  &channel_new_cb,
1300  listener,
1302  &channel_end_cb,
1303  cadet_handlers);
1305 }
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
Actual set elements.
State we keep per client.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF
Bloom filter message for intersection exchange started by Bob.
Message containing buckets of an invertible bloom filter.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
enum GNUNET_SET_OperationType operation
The type of the operation.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void channel_window_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
uint32_t operation
Operation type, values of enum GNUNET_SET_OperationType
Definition: set.h:69
#define GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST
Request a set operation from a remote peer.
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incomming MQ-based channels.
Definition: cadet_api.c:1010
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE
Strata estimator.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
Message handler for a specific message type.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
Bloom filter messages exchanged for set intersection calculation.
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
static void * channel_new_cb(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
Method called whenever another peer has added us to a channel the other peer initiated.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
Information about the element count for intersection.
Strata estimator together with the peer&#39;s overall set size.
GNUNET_SET_OperationType
The operation that a set set supports.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF
Invertible bloom filter.
static void channel_end_cb(void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
During intersection, the first (and possibly second) message send it the number of elements in the se...
struct GNUNET_HashCode app_id
application id
Definition: set.h:74
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE
Intersection operation is done.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:280
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Header for all communications.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Last message, send to confirm the final set.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER
Request all missing elements from the other peer, based on their sets and the elements we previously ...
struct ClientState * cs
Client that owns the listener.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY
Tell the other peer to send us a list of hashes that match an IBF key.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static struct Listener * listener_head
Listeners are held in a doubly linked list.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
Here is the call graph for this function:

◆ handle_client_reject()

static void handle_client_reject ( void *  cls,
const struct GNUNET_SET_RejectMessage msg 
)
static

Called when the listening client rejects an operation request by another peer.

Parameters
clsclient that sent the message
msgmessage sent by the client

Definition at line 1316 of file gnunet-service-set.c.

References _GSS_operation_destroy2(), GNUNET_SET_RejectMessage::accept_reject_id, Listener::app_id, ClientState::client, get_incoming(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_h2s(), GNUNET_log, GNUNET_SERVICE_client_continue(), ClientState::listener, Operation::listener, op, and Listener::operation.

1317 {
1318  struct ClientState *cs = cls;
1319  struct Operation *op;
1320 
1321  op = get_incoming (ntohl (msg->accept_reject_id));
1322  if (NULL == op)
1323  {
1324  /* no matching incoming operation for this reject;
1325  could be that the other peer already disconnected... */
1327  "Client rejected unknown operation %u\n",
1328  (unsigned int) ntohl (msg->accept_reject_id));
1330  return;
1331  }
1333  "Peer request (op %u, app %s) rejected by client\n",
1334  op->listener->operation,
1335  GNUNET_h2s (&cs->listener->app_id));
1338 }
State we keep per client.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
enum GNUNET_SET_OperationType operation
The type of the operation.
struct Listener * listener
Port this operation runs on.
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
Operation context used to execute a set operation.
uint32_t accept_reject_id
ID of the incoming request we want to reject.
Definition: set.h:145
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
static struct Operation * get_incoming(uint32_t id)
Get the incoming socket associated with the given id.
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ check_client_mutation()

static int check_client_mutation ( void *  cls,
const struct GNUNET_SET_ElementMessage msg 
)
static

Called when a client wants to add or remove an element to a set it inhabits.

Parameters
clsclient that sent the message
msgmessage sent by the client

Definition at line 1348 of file gnunet-service-set.c.

References GNUNET_OK.

1349 {
1350  /* NOTE: Technically, we should probably check with the
1351  block library whether the element we are given is well-formed */
1352  return GNUNET_OK;
1353 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75

◆ handle_client_mutation()

static void handle_client_mutation ( void *  cls,
const struct GNUNET_SET_ElementMessage msg 
)
static

Called when a client wants to add or remove an element to a set it inhabits.

Parameters
clsclient that sent the message
msgmessage sent by the client

Definition at line 1363 of file gnunet-service-set.c.

References ClientState::client, execute_mutation(), GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_copy_message(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SET_ElementMessage::header, PendingMutation::msg, pm, ClientState::set, and PendingMutation::set.

1364 {
1365  struct ClientState *cs = cls;
1366  struct Set *set;
1367 
1368  if (NULL == (set = cs->set))
1369  {
1370  /* client without a set requested an operation */
1371  GNUNET_break (0);
1373  return;
1374  }
1376 
1377  if (0 != set->content->iterator_count)
1378  {
1379  struct PendingMutation *pm;
1380 
1381  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduling mutation on set\n");
1382  pm = GNUNET_new (struct PendingMutation);
1383  pm->msg =
1385  pm->set = set;
1386  GNUNET_CONTAINER_DLL_insert_tail (set->content->pending_mutations_head,
1387  set->content->pending_mutations_tail,
1388  pm);
1389  return;
1390  }
1391  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing mutation on set\n");
1392  execute_mutation (set, msg);
1393 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:286
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void execute_mutation(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Perform a mutation on a set as specified by the msg.
Information about a mutation to apply to a set.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct Set * set
Set this mutation is about.
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:280
struct GNUNET_SET_ElementMessage * msg
Message that describes the desired mutation.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
Here is the call graph for this function:

◆ advance_generation()

static void advance_generation ( struct Set set)
static

Advance the current generation of a set, adding exclusion ranges if necessary.

Parameters
setthe set where we want to advance the generation

Definition at line 1403 of file gnunet-service-set.c.

References GenerationRange::end, GNUNET_array_append, GNUNET_assert, and GenerationRange::start.

Referenced by handle_client_accept(), handle_client_copy_lazy_connect(), and handle_client_evaluate().

1404 {
1405  struct GenerationRange r;
1406 
1407  if (set->current_generation == set->content->latest_generation)
1408  {
1409  set->content->latest_generation++;
1410  set->current_generation++;
1411  return;
1412  }
1413 
1415 
1416  r.start = set->current_generation + 1;
1417  r.end = set->content->latest_generation + 1;
1418  set->content->latest_generation = r.end;
1419  set->current_generation = r.end;
1422  r);
1423 }
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
unsigned int latest_generation
FIXME: document!
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
unsigned int current_generation
Current generation, that is, number of previously executed operations and lazy copies on the underlyi...
#define GNUNET_array_append(arr, size, element)
Append an element to a list (growing the list by one).
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the caller graph for this function:

◆ check_client_evaluate()

static int check_client_evaluate ( void *  cls,
const struct GNUNET_SET_EvaluateMessage msg 
)
static

Called when a client wants to initiate a set operation with another peer.

Initiates the CADET connection to the listener and sends the request.

Parameters
clsclient that sent the message
msgmessage sent by the client
Returns
GNUNET_OK if the message is well-formed

Definition at line 1436 of file gnunet-service-set.c.

References GNUNET_OK.

1437 {
1438  /* FIXME: suboptimal, even if the context below could be NULL,
1439  there are malformed messages this does not check for... */
1440  return GNUNET_OK;
1441 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75

◆ handle_client_evaluate()

static void handle_client_evaluate ( void *  cls,
const struct GNUNET_SET_EvaluateMessage msg 
)
static

Called when a client wants to initiate a set operation with another peer.

Initiates the CADET connection to the listener and sends the request.

Parameters
clsclient that sent the message
msgmessage sent by the client

Definition at line 1453 of file gnunet-service-set.c.

References advance_generation(), GNUNET_SET_EvaluateMessage::app_id, GNUNET_SET_EvaluateMessage::byzantine, Operation::byzantine, GNUNET_SET_EvaluateMessage::byzantine_lower_bound, Operation::byzantine_lower_bound, Operation::channel, channel_end_cb(), channel_window_cb(), ClientState::client, Operation::client_request_id, context, GNUNET_SET_EvaluateMessage::force_delta, Operation::force_delta, GNUNET_SET_EvaluateMessage::force_full, Operation::force_full, Operation::generation_created, GNUNET_break, GNUNET_CADET_channel_create(), GNUNET_CADET_get_mq(), GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE, GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC, GNUNET_MQ_extract_nested_mh, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), Operation::mq, op, Operation::peer, GNUNET_SET_EvaluateMessage::request_id, GNUNET_SET_EvaluateMessage::result_mode, Operation::result_mode, Operation::salt, ClientState::set, Operation::set, Operation::state, and GNUNET_SET_EvaluateMessage::target_peer.

1454 {
1455  struct ClientState *cs = cls;
1456  struct Operation *op = GNUNET_new (struct Operation);
1457  const struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1458  { GNUNET_MQ_hd_var_size (incoming_msg,
1460  struct OperationRequestMessage,
1461  op),
1462  GNUNET_MQ_hd_var_size (union_p2p_ibf,
1464  struct IBFMessage,
1465  op),
1466  GNUNET_MQ_hd_var_size (union_p2p_elements,
1469  op),
1470  GNUNET_MQ_hd_var_size (union_p2p_offer,
1472  struct GNUNET_MessageHeader,
1473  op),
1474  GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1476  struct InquiryMessage,
1477  op),
1478  GNUNET_MQ_hd_var_size (union_p2p_demand,
1480  struct GNUNET_MessageHeader,
1481  op),
1482  GNUNET_MQ_hd_fixed_size (union_p2p_done,
1484  struct GNUNET_MessageHeader,
1485  op),
1486  GNUNET_MQ_hd_fixed_size (union_p2p_over,
1488  struct GNUNET_MessageHeader,
1489  op),
1490  GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1492  struct GNUNET_MessageHeader,
1493  op),
1494  GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1496  struct GNUNET_MessageHeader,
1497  op),
1498  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1500  struct StrataEstimatorMessage,
1501  op),
1502  GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1504  struct StrataEstimatorMessage,
1505  op),
1506  GNUNET_MQ_hd_var_size (union_p2p_full_element,
1509  op),
1510  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1513  op),
1514  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1516  struct BFMessage,
1517  op),
1518  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1520  struct IntersectionDoneMessage,
1521  op),
1522  GNUNET_MQ_handler_end () };
1523  struct Set *set;
1524  const struct GNUNET_MessageHeader *context;
1525 
1526  if (NULL == (set = cs->set))
1527  {
1528  GNUNET_break (0);
1529  GNUNET_free (op);
1531  return;
1532  }
1534  op->peer = msg->target_peer;
1535  op->result_mode = ntohl (msg->result_mode);
1536  op->client_request_id = ntohl (msg->request_id);
1537  op->byzantine = msg->byzantine;
1539  op->force_full = msg->force_full;
1540  op->force_delta = msg->force_delta;
1541  context = GNUNET_MQ_extract_nested_mh (msg);
1542 
1543  /* Advance generation values, so that
1544  mutations won't interfer with the running operation. */
1545  op->set = set;
1546  op->generation_created = set->current_generation;
1547  advance_generation (set);
1548  GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op);
1550  "Creating new CADET channel to port %s for set operation type %u\n",
1551  GNUNET_h2s (&msg->app_id),
1552  set->operation);
1554  op,
1555  &msg->target_peer,
1556  &msg->app_id,
1558  &channel_end_cb,
1559  cadet_handlers);
1560  op->mq = GNUNET_CADET_get_mq (op->channel);
1561  op->state = set->vt->evaluate (op, context);
1562  if (NULL == op->state)
1563  {
1564  GNUNET_break (0);
1566  return;
1567  }
1569 }
struct GNUNET_PeerIdentity target_peer
Peer to evaluate the operation with.
Definition: set.h:196
struct Set * set
Set, if associated with the client, otherwise NULL.
#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
Actual set elements.
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
State we keep per client.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
int byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF
Bloom filter message for intersection exchange started by Bob.
Message containing buckets of an invertible bloom filter.
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:191
uint8_t force_full
Always send full sets, even if delta operations would be more efficient.
Definition: set.h:219
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int generation_created
Generation in which the operation handle was created.
static pa_context * context
Pulseaudio context.
static void channel_window_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
#define GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST
Request a set operation from a remote peer.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
uint8_t force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
Definition: set.h:213
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE
Strata estimator.
A set that supports a specific operation with other peers.
Randomness for IVs etc.
uint32_t request_id
Id of our set to evaluate, chosen implicitly by the client when it calls GNUNET_SET_commit().
Definition: set.h:207
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
Message handler for a specific message type.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
Bloom filter messages exchanged for set intersection calculation.
int force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
uint8_t byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Definition: set.h:225
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
uint8_t byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
Definition: set.h:231
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
Information about the element count for intersection.
Strata estimator together with the peer&#39;s overall set size.
Operation context used to execute a set operation.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF
Invertible bloom filter.
static void channel_end_cb(void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
During intersection, the first (and possibly second) message send it the number of elements in the se...
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1068
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
struct GNUNET_HashCode app_id
Application id.
Definition: set.h:201
uint32_t salt
Salt to use for the operation.
struct GNUNET_SERVICE_Client * client
Client this is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE
Intersection operation is done.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:280
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
Header for all communications.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Last message, send to confirm the final set.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER
Request all missing elements from the other peer, based on their sets and the elements we previously ...
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY
Tell the other peer to send us a list of hashes that match an IBF key.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1119
int force_full
Always send full sets, even if delta operations would be more efficient.
Here is the call graph for this function:

◆ handle_client_iter_ack()

static void handle_client_iter_ack ( void *  cls,
const struct GNUNET_SET_IterAckMessage ack 
)
static

Handle an ack from a client, and send the next element.

Note that we only expect acks for set elements, not after the GNUNET_MESSAGE_TYPE_SET_ITER_DONE message.

Parameters
clsclient the client
ackthe message

Definition at line 1581 of file gnunet-service-set.c.

References ClientState::client, GNUNET_break, GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), send_client_element(), GNUNET_SET_IterAckMessage::send_more, and ClientState::set.

1582 {
1583  struct ClientState *cs = cls;
1584  struct Set *set;
1585 
1586  if (NULL == (set = cs->set))
1587  {
1588  /* client without a set acknowledged receiving a value */
1589  GNUNET_break (0);
1591  return;
1592  }
1593  if (NULL == set->iter)
1594  {
1595  /* client sent an ack, but we were not expecting one (as
1596  set iteration has finished) */
1597  GNUNET_break (0);
1599  return;
1600  }
1602  if (ntohl (ack->send_more))
1603  {
1604  send_client_element (set);
1605  }
1606  else
1607  {
1609  set->iter = NULL;
1610  set->iteration_id++;
1611  }
1612 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
static void send_client_element(struct Set *set)
Send the next element of a set to the set&#39;s client.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
struct GNUNET_SERVICE_Client * client
Client this is about.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
uint32_t send_more
Non-zero if the service should continue sending elements.
Definition: set.h:360
Here is the call graph for this function:

◆ handle_client_copy_lazy_prepare()

static void handle_client_copy_lazy_prepare ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Handle a request from the client to copy a set.

Parameters
clsthe client
mhthe message

Definition at line 1622 of file gnunet-service-set.c.

References ClientState::client, LazyCopyRequest::cookie, GNUNET_SET_CopyLazyResponseMessage::cookie, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), lazy_copy_cookie, ClientState::set, and LazyCopyRequest::source_set.

1624 {
1625  struct ClientState *cs = cls;
1626  struct Set *set;
1627  struct LazyCopyRequest *cr;
1628  struct GNUNET_MQ_Envelope *ev;
1629  struct GNUNET_SET_CopyLazyResponseMessage *resp_msg;
1630 
1631  if (NULL == (set = cs->set))
1632  {
1633  /* client without a set requested an operation */
1634  GNUNET_break (0);
1636  return;
1637  }
1639  "Client requested creation of lazy copy\n");
1640  cr = GNUNET_new (struct LazyCopyRequest);
1641  cr->cookie = ++lazy_copy_cookie;
1642  cr->source_set = set;
1645  resp_msg->cookie = cr->cookie;
1646  GNUNET_MQ_send (set->cs->mq, ev);
1648 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE
Give the client an ID for connecting to the set&#39;s copy.
static uint32_t lazy_copy_cookie
Generator for unique cookie we set per lazy copy request.
uint32_t cookie
Cookie identifying the request.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
struct Set * source_set
Which set are we supposed to copy?
static struct LazyCopyRequest * lazy_copy_tail
DLL of lazy copy requests by this client.
struct GNUNET_SERVICE_Client * client
Client this is about.
Server responds to a lazy copy request.
Definition: set.h:367
#define GNUNET_log(kind,...)
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:377
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:353
static struct LazyCopyRequest * lazy_copy_head
DLL of lazy copy requests by this client.
Lazy copy requests made by a client.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ handle_client_copy_lazy_connect()

static void handle_client_copy_lazy_connect ( void *  cls,
const struct GNUNET_SET_CopyLazyConnectMessage msg 
)
static

Handle a request from the client to connect to a copy of a set.

Parameters
clsthe client
msgthe message

Definition at line 1658 of file gnunet-service-set.c.

References _GSS_intersection_vt(), _GSS_union_vt(), advance_generation(), ClientState::client, Set::content, LazyCopyRequest::cookie, GNUNET_SET_CopyLazyConnectMessage::cookie, Set::cs, Set::current_generation, Set::excluded_generations, Set::excluded_generations_size, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_memdup, GNUNET_new, GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SET_OPERATION_INTERSECTION, GNUNET_SET_OPERATION_UNION, GNUNET_YES, LazyCopyRequest::next, Set::operation, SetContent::refcount, ClientState::set, LazyCopyRequest::source_set, and Set::state.

1661 {
1662  struct ClientState *cs = cls;
1663  struct LazyCopyRequest *cr;
1664  struct Set *set;
1665  int found;
1666 
1667  if (NULL != cs->set)
1668  {
1669  /* There can only be one set per client */
1670  GNUNET_break (0);
1672  return;
1673  }
1674  found = GNUNET_NO;
1675  for (cr = lazy_copy_head; NULL != cr; cr = cr->next)
1676  {
1677  if (cr->cookie == msg->cookie)
1678  {
1679  found = GNUNET_YES;
1680  break;
1681  }
1682  }
1683  if (GNUNET_NO == found)
1684  {
1685  /* client asked for copy with cookie we don't know */
1686  GNUNET_break (0);
1688  return;
1689  }
1692  "Client %p requested use of lazy copy\n",
1693  cs);
1694  set = GNUNET_new (struct Set);
1695  switch (cr->source_set->operation)
1696  {
1698  set->vt = _GSS_intersection_vt ();
1699  break;
1700 
1702  set->vt = _GSS_union_vt ();
1703  break;
1704 
1705  default:
1706  GNUNET_assert (0);
1707  return;
1708  }
1709 
1710  if (NULL == set->vt->copy_state)
1711  {
1712  /* Lazy copy not supported for this set operation */
1713  GNUNET_break (0);
1714  GNUNET_free (set);
1715  GNUNET_free (cr);
1717  return;
1718  }
1719 
1720  set->operation = cr->source_set->operation;
1721  set->state = set->vt->copy_state (cr->source_set->state);
1722  set->content = cr->source_set->content;
1723  set->content->refcount++;
1724 
1725  set->current_generation = cr->source_set->current_generation;
1726  set->excluded_generations_size = cr->source_set->excluded_generations_size;
1727  set->excluded_generations =
1729  set->excluded_generations_size
1730  * sizeof(struct GenerationRange));
1731 
1732  /* Advance the generation of the new set, so that mutations to the
1733  of the cloned set and the source set are independent. */
1734  advance_generation (set);
1735  set->cs = cs;
1736  cs->set = set;
1737  GNUNET_free (cr);
1739 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct Set * set
Set, if associated with the client, otherwise NULL.
const struct SetVT * _GSS_intersection_vt(void)
Get the table with implementing functions for set intersection.
State we keep per client.
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
struct SetState * state
Implementation-specific state.
unsigned int refcount
Number of references to the content.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint32_t cookie
Cookie identifying the request.
unsigned int excluded_generations_size
Number of elements in array excluded_generations.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int current_generation
Current generation, that is, number of previously executed operations and lazy copies on the underlyi...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:394
struct Set * source_set
Which set are we supposed to copy?
static struct LazyCopyRequest * lazy_copy_tail
DLL of lazy copy requests by this client.
struct LazyCopyRequest * next
Kept in a DLL.
struct GNUNET_SERVICE_Client * client
Client this is about.
const struct SetVT * _GSS_union_vt(void)
Get the table with implementing functions for set union.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
struct ClientState * cs
Client that owns the set.
Set intersection, only return elements that are in both sets.
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
Set union, return all elements that are in at least one of the sets.
static struct LazyCopyRequest * lazy_copy_head
DLL of lazy copy requests by this client.
Lazy copy requests made by a client.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define GNUNET_free(ptr)
Wrapper around free.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the call graph for this function:

◆ handle_client_cancel()

static void handle_client_cancel ( void *  cls,
const struct GNUNET_SET_CancelMessage msg 
)
static

Handle a request from the client to cancel a running set operation.

Parameters
clsthe client
msgthe message

Definition at line 1749 of file gnunet-service-set.c.

References _GSS_operation_destroy(), ClientState::client, Operation::client_request_id, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_YES, Operation::next, op, Set::ops_head, GNUNET_SET_CancelMessage::request_id, ClientState::set, and Operation::set.

1750 {
1751  struct ClientState *cs = cls;
1752  struct Set *set;
1753  struct Operation *op;
1754  int found;
1755 
1756  if (NULL == (set = cs->set))
1757  {
1758  /* client without a set requested an operation */
1759  GNUNET_break (0);
1761  return;
1762  }
1763  found = GNUNET_NO;
1764  for (op = set->ops_head; NULL != op; op = op->next)
1765  {
1766  if (op->client_request_id == ntohl (msg->request_id))
1767  {
1768  found = GNUNET_YES;
1769  break;
1770  }
1771  }
1772  if (GNUNET_NO == found)
1773  {
1774  /* It may happen that the operation was already destroyed due to
1775  * the other peer disconnecting. The client may not know about this
1776  * yet and try to cancel the (just barely non-existent) operation.
1777  * So this is not a hard error.
1779  "Client canceled non-existent op %u\n",
1780  (uint32_t) ntohl (msg->request_id));
1781  }
1782  else
1783  {
1785  "Client requested cancel for op %u\n",
1786  (uint32_t) ntohl (msg->request_id));
1788  }
1790 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_NO
Definition: gnunet_common.h:78
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
struct Operation * ops_head
Evaluate operations are held in a linked list.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
Operation context used to execute a set operation.
struct Operation * next
Kept in a DLL of the listener, if listener is non-NULL.
struct GNUNET_SERVICE_Client * client
Client this is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
uint32_t request_id
ID of the request we want to cancel.
Definition: set.h:316
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ handle_client_accept()

static void handle_client_accept ( void *  cls,
const struct GNUNET_SET_AcceptMessage msg 
)
static

Handle a request from the client to accept a set operation that came from a remote peer.

We forward the accept to the associated operation for handling

Parameters
clsthe client
msgthe message

Definition at line 1802 of file gnunet-service-set.c.

References GNUNET_SET_AcceptMessage::accept_reject_id, advance_generation(), GNUNET_SET_AcceptMessage::byzantine, Operation::byzantine, GNUNET_SET_AcceptMessage::byzantine_lower_bound, Operation::byzantine_lower_bound, Operation::channel, ClientState::client, Operation::client_request_id, GNUNET_SET_AcceptMessage::force_delta, Operation::force_delta, GNUNET_SET_AcceptMessage::force_full, Operation::force_full, Operation::generation_created, get_incoming(), GNUNET_assert, GNUNET_break, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SET_STATUS_FAILURE, ClientState::listener, Operation::listener, op, Listener::op_head, Listener::op_tail, GNUNET_SET_AcceptMessage::request_id, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_AcceptMessage::result_mode, Operation::result_mode, GNUNET_SET_ResultMessage::result_status, ClientState::set, Operation::set, and Operation::state.

1803 {
1804  struct ClientState *cs = cls;
1805  struct Set *set;
1806  struct Operation *op;
1807  struct GNUNET_SET_ResultMessage *result_message;
1808  struct GNUNET_MQ_Envelope *ev;
1809  struct Listener *listener;
1810 
1811  if (NULL == (set = cs->set))
1812  {
1813  /* client without a set requested to accept */
1814  GNUNET_break (0);
1816  return;
1817  }
1818  op = get_incoming (ntohl (msg->accept_reject_id));
1819  if (NULL == op)
1820  {
1821  /* It is not an error if the set op does not exist -- it may
1822  * have been destroyed when the partner peer disconnected. */
1823  GNUNET_log (
1825  "Client %p accepted request %u of listener %p that is no longer active\n",
1826  cs,
1827  ntohl (msg->accept_reject_id),
1828  cs->listener);
1829  ev = GNUNET_MQ_msg (result_message, GNUNET_MESSAGE_TYPE_SET_RESULT);
1830  result_message->request_id = msg->request_id;
1831  result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE);
1832  GNUNET_MQ_send (set->cs->mq, ev);
1834  return;
1835  }
1837  "Client accepting request %u\n",
1838  (uint32_t) ntohl (msg->accept_reject_id));
1839  listener = op->listener;
1840  op->listener = NULL;
1841  GNUNET_CONTAINER_DLL_remove (listener->op_head, listener->op_tail, op);
1842  op->set = set;
1843  GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op);
1844  op->client_request_id = ntohl (msg->request_id);
1845  op->result_mode = ntohl (msg->result_mode);
1846  op->byzantine = msg->byzantine;
1848  op->force_full = msg->force_full;
1849  op->force_delta = msg->force_delta;
1850 
1851  /* Advance generation values, so that future mutations do not
1852  interfer with the running operation. */
1853  op->generation_created = set->current_generation;
1854  advance_generation (set);
1855  GNUNET_assert (NULL == op->state);
1856  op->state = set->vt->accept (op);
1857  if (NULL == op->state)
1858  {
1859  GNUNET_break (0);
1861  return;
1862  }
1863  /* Now allow CADET to continue, as we did not do this in
1864  #handle_incoming_msg (as we wanted to first see if the
1865  local client would accept the request). */
1868 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct Set * set
Set, if associated with the client, otherwise NULL.
enum GNUNET_SET_ResultMode result_mode
When are elements sent to the client, and which elements are sent?
State we keep per client.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:244
uint32_t request_id
Request ID to identify responses.
Definition: set.h:97
uint8_t force_full
Always send full sets, even if delta operations would be more efficient.
Definition: set.h:115
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint8_t force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
Definition: set.h:109
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
uint32_t request_id
id the result belongs to
Definition: set.h:259
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
uint8_t byzantine_lower_bound
Lower bound for the set size, used only when byzantine mode is enabled.
Definition: set.h:127
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int generation_created
Generation in which the operation handle was created.
The other peer refused to to the operation with us, or something went wrong.
struct Listener * listener
Port this operation runs on.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:265
A set that supports a specific operation with other peers.
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
int force_delta
Always use delta operation instead of sending full sets, even it it&#39;s less efficient.
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
uint32_t result_mode
How should results be sent to us? See enum GNUNET_SET_ResultMode.
Definition: set.h:103
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Operation context used to execute a set operation.
uint32_t accept_reject_id
ID of the incoming request we want to accept.
Definition: set.h:92
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:954
struct GNUNET_SERVICE_Client * client
Client this is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
static struct Operation * get_incoming(uint32_t id)
Get the incoming socket associated with the given id.
uint8_t byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Definition: set.h:121
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:353
struct OperationState * state
Operation-specific operation state.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
int force_full
Always send full sets, even if delta operations would be more efficient.
Here is the call graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Called to clean up, after a shutdown has been requested.

Parameters
clsclosure, NULL

Definition at line 1877 of file gnunet-service-set.c.

References GNUNET_CADET_disconnect(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_STATISTICS_destroy(), GNUNET_YES, in_shutdown, and num_clients.

Referenced by run().

1878 {
1879  /* Delay actual shutdown to allow service to disconnect clients */
1881  if (0 == num_clients)
1882  {
1883  if (NULL != cadet)
1884  {
1886  cadet = NULL;
1887  }
1888  }
1890  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handled shutdown request\n");
1891 }
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:841
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
static unsigned int num_clients
Number of active clients.
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET...
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle cfg,
struct GNUNET_SERVICE_Handle service 
)
static

Function called by the service's run method to run service-specific setup code.

Parameters
clsclosure
cfgconfiguration to use
servicethe initialized service

Definition at line 1903 of file gnunet-service-set.c.

References _, client_connect_cb(), client_disconnect_cb(), GNUNET_CADET_connect(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_ACCEPT, GNUNET_MESSAGE_TYPE_SET_ADD, GNUNET_MESSAGE_TYPE_SET_CANCEL, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE, GNUNET_MESSAGE_TYPE_SET_CREATE, GNUNET_MESSAGE_TYPE_SET_EVALUATE, GNUNET_MESSAGE_TYPE_SET_ITER_ACK, GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST, GNUNET_MESSAGE_TYPE_SET_LISTEN, GNUNET_MESSAGE_TYPE_SET_REJECT, GNUNET_MESSAGE_TYPE_SET_REMOVE, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_NONE, GNUNET_STATISTICS_create(), and shutdown_task().

1906 {
1907  /* FIXME: need to modify SERVICE (!) API to allow
1908  us to run a shutdown task *after* clients were
1909  forcefully disconnected! */
1912  cadet = GNUNET_CADET_connect (cfg);
1913  if (NULL == cadet)
1914  {
1916  _ ("Could not connect to CADET service\n"));
1918  return;
1919  }
1920 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static void shutdown_task(void *cls)
Called to clean up, after a shutdown has been requested.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:976
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
#define GNUNET_log(kind,...)
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( "set"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
client_connect_cb,
client_disconnect_cb,
NULL  ,
GNUNET_MQ_hd_fixed_size(client_accept, GNUNET_MESSAGE_TYPE_SET_ACCEPT, struct GNUNET_SET_AcceptMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_iter_ack, GNUNET_MESSAGE_TYPE_SET_ITER_ACK, struct GNUNET_SET_IterAckMessage, NULL)  ,
GNUNET_MQ_hd_var_size(client_mutation, GNUNET_MESSAGE_TYPE_SET_ADD, struct GNUNET_SET_ElementMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_create_set, GNUNET_MESSAGE_TYPE_SET_CREATE, struct GNUNET_SET_CreateMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_iterate, GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST, struct GNUNET_MessageHeader, NULL)  ,
GNUNET_MQ_hd_var_size(client_evaluate, GNUNET_MESSAGE_TYPE_SET_EVALUATE, struct GNUNET_SET_EvaluateMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_listen, GNUNET_MESSAGE_TYPE_SET_LISTEN, struct GNUNET_SET_ListenMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_reject, GNUNET_MESSAGE_TYPE_SET_REJECT, struct GNUNET_SET_RejectMessage, NULL)  ,
GNUNET_MQ_hd_var_size(client_mutation, GNUNET_MESSAGE_TYPE_SET_REMOVE, struct GNUNET_SET_ElementMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_cancel, GNUNET_MESSAGE_TYPE_SET_CANCEL, struct GNUNET_SET_CancelMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_copy_lazy_prepare, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE, struct GNUNET_MessageHeader, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_copy_lazy_connect, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT, struct GNUNET_SET_CopyLazyConnectMessage, NULL)  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Referenced by run().

Here is the caller graph for this function:

Variable Documentation

◆ cadet

struct GNUNET_CADET_Handle* cadet
static

Handle to the cadet service, used to listen for and connect to remote peers.

Definition at line 124 of file gnunet-service-set.c.

◆ lazy_copy_head

struct LazyCopyRequest* lazy_copy_head
static

DLL of lazy copy requests by this client.

Definition at line 129 of file gnunet-service-set.c.

Referenced by client_disconnect_cb().

◆ lazy_copy_tail

struct LazyCopyRequest* lazy_copy_tail
static

DLL of lazy copy requests by this client.

Definition at line 134 of file gnunet-service-set.c.

◆ lazy_copy_cookie

uint32_t lazy_copy_cookie
static

Generator for unique cookie we set per lazy copy request.

Definition at line 139 of file gnunet-service-set.c.

Referenced by handle_client_copy_lazy_prepare().

◆ _GSS_statistics

struct GNUNET_STATISTICS_Handle* _GSS_statistics

◆ listener_head

struct Listener* listener_head
static

Listeners are held in a doubly linked list.

Definition at line 149 of file gnunet-service-set.c.

◆ listener_tail

struct Listener* listener_tail
static

Listeners are held in a doubly linked list.

Definition at line 154 of file gnunet-service-set.c.

◆ num_clients

unsigned int num_clients
static

Number of active clients.

Definition at line 159 of file gnunet-service-set.c.

Referenced by client_connect_cb(), client_disconnect_cb(), and shutdown_task().

◆ in_shutdown

int in_shutdown
static

Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET.

Definition at line 165 of file gnunet-service-set.c.

Referenced by client_disconnect_cb(), and shutdown_task().

◆ suggest_id

uint32_t suggest_id
static

Counter for allocating unique IDs for clients, used to identify incoming operation requests from remote peers, that the client can choose to accept or refuse.

0 must not be used (reserved for uninitialized).

Definition at line 173 of file gnunet-service-set.c.

Referenced by handle_incoming_msg().