GNUnet 0.22.2
gnunet-service-set.c File Reference

two-peer set operations More...

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 (GNUNET_OS_project_data_gnunet(), "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 37 of file gnunet-service-set.c.

Function Documentation

◆ get_incoming()

static struct Operation * get_incoming ( uint32_t  id)
static

Get the incoming socket associated with the given id.

Parameters
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.

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}
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:143
static struct Listener * listener_head
Listeners are held in a doubly linked list.
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.
struct Listener * next
Listeners are held in a doubly linked list.
Operation context used to execute a set operation.

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

Referenced by handle_client_accept(), and handle_client_reject().

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.

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 {
218 GNUNET_SCHEDULER_cancel (op->timeout_task);
219 op->timeout_task = NULL;
220 }
222}
void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
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.

References _GSS_operation_destroy2(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_cancel(), op, Listener::op_head, and Listener::op_tail.

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

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.

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}
@ GNUNET_OK

References GNUNET_OK.

Referenced by collect_generation_garbage().

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.

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}
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...
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_MAX(a, b)
#define GNUNET_MIN(a, b)
Context for the garbage_collect_cb().
unsigned int min_op_generation
Lowest generation for which an operation is still pending.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
struct Operation * ops_head
Evaluate operations are held in a linked list.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.

References Set::content, SetContent::elements, 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, op, and Set::ops_head.

Referenced by _GSS_operation_destroy().

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.

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 start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
@ GNUNET_YES
@ GNUNET_NO

References end, GNUNET_NO, GNUNET_YES, and start.

Referenced by is_element_of_generation().

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.

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}
static int is_excluded_generation(unsigned int generation, struct GenerationRange *excluded, unsigned int excluded_size)
Is generation in the range of exclusions?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
struct MutationEvent * mutations
If mutations is not NULL, it contains a list of mutations, ordered by increasing generation.
unsigned int mutations_size
Number of elements in the array mutations.
MutationEvent gives information about changes to an element (removal / addition) in a set content.
unsigned int generation
First generation affected by this mutation event.
int added
If added is GNUNET_YES, then this is a remove event, otherwise it is an add event.

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().

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.

399{
400 return is_element_of_generation (ee,
401 op->generation_created,
402 op->set->excluded_generations,
403 op->set->excluded_generations_size);
404}
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?

References is_element_of_generation(), and op.

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

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.

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 {
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}
static void collect_generation_garbage(struct Set *set)
Collect and destroy elements that are not needed anymore, because their lifetime (as determined by th...
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:833
#define GNUNET_free(ptr)
Wrapper around free.
Opaque handle to a channel.
Definition: cadet.h:116
OpCancelImpl cancel
Callback for canceling an operation.
A set that supports a specific operation with other peers.
struct Operation * ops_tail
Evaluate operations are held in a linked list.
const struct SetVT * vt
Virtual table for this set.

References SetVT::cancel, collect_generation_garbage(), GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_YES, op, Set::ops_head, Set::ops_tail, and Set::vt.

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().

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.

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}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static unsigned int num_clients
Number of active clients.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
struct GNUNET_SERVICE_Client * client
Client this is about.

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

◆ 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.

492{
493 struct ElementEntry *ee = value;
494
496 GNUNET_free (ee);
497 return GNUNET_YES;
498}
static char * value
Value of the record to add/remove.
Information about an element element in the set.

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

Referenced by client_disconnect_cb().

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.

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)
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 }
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));
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}
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET.
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
static struct LazyCopyRequest * lazy_copy_head
DLL of lazy copy requests by this client.
static struct LazyCopyRequest * lazy_copy_tail
DLL of lazy copy requests by this client.
void _GSS_operation_destroy(struct Operation *op, int gc)
Destroy the given operation.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:777
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition: cadet_api.c:804
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_INFO
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
struct Set * set
Set, if associated with the client, otherwise NULL.
Lazy copy requests made by a client.
struct LazyCopyRequest * next
Kept in a DLL.
struct Set * source_set
Which set are we supposed to copy?
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
Information about a mutation to apply to a set.
struct Set * set
Set this mutation is about.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
struct PendingMutation * pending_mutations_head
Mutations requested by the client that we're unable to execute right now because we're iterating over...
unsigned int refcount
Number of references to the content.
struct PendingMutation * pending_mutations_tail
Mutations requested by the client that we're unable to execute right now because we're iterating over...
SetDestroyImpl destroy_set
Callback for destruction of the set state.
struct SetState * state
Implementation-specific state.
uint16_t iteration_id
Each iter is assigned a unique number, so that the client can distinguish iterations.
struct GenerationRange * excluded_generations
List of generations we have to exclude, due to lazy copies.
struct GNUNET_CONTAINER_MultiHashMapIterator * iter
Current state of iterating elements for the client.
struct ClientState * cs
Client that owns the set.

References _GSS_operation_destroy(), cadet, Set::content, Set::cs, destroy_elements_iterator(), SetVT::destroy_set, SetContent::elements, Set::excluded_generations, 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_i2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, in_shutdown, incoming_destroy(), Set::iter, Set::iteration_id, lazy_copy_head, lazy_copy_tail, ClientState::listener, listener_head, listener_tail, LazyCopyRequest::next, num_clients, op, Listener::op_head, Listener::open_port, Set::ops_head, SetContent::pending_mutations_head, SetContent::pending_mutations_tail, pm, SetContent::refcount, ClientState::set, PendingMutation::set, LazyCopyRequest::source_set, Set::state, and Set::vt.

Here is the call 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.

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 != ntohl (msg->operation))
651 {
652 GNUNET_break_op (0);
653 return GNUNET_SYSERR;
654 }
655 nested_context = GNUNET_MQ_extract_nested_mh (msg);
656 if ((NULL != nested_context) &&
657 (ntohs (nested_context->size) > GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE))
658 {
659 GNUNET_break_op (0);
660 return GNUNET_SYSERR;
661 }
662 return GNUNET_OK;
663}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
#define GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
Header for all communications.
enum GNUNET_SET_OperationType operation
The type of the operation.

References GNUNET_break, GNUNET_break_op, GNUNET_MQ_extract_nested_mh, GNUNET_OK, GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE, GNUNET_SYSERR, msg, op, Listener::operation, and GNUNET_MessageHeader::size.

◆ 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 684 of file gnunet-service-set.c.

685{
686 struct Operation *op = cls;
687 struct Listener *listener = op->listener;
688 const struct GNUNET_MessageHeader *nested_context;
689 struct GNUNET_MQ_Envelope *env;
690 struct GNUNET_SET_RequestMessage *cmsg;
691
692 nested_context = GNUNET_MQ_extract_nested_mh (msg);
693 /* Make a copy of the nested_context (application-specific context
694 information that is opaque to set) so we can pass it to the
695 listener later on */
696 if (NULL != nested_context)
697 op->context_msg = GNUNET_copy_message (nested_context);
698 op->remote_element_count = ntohl (msg->element_count);
699 GNUNET_log (
701 "Received P2P operation request (op %u, port %s) for active listener\n",
702 (uint32_t) ntohl (msg->operation),
703 GNUNET_h2s (&op->listener->app_id));
704 GNUNET_assert (0 == op->suggest_id);
705 if (0 == suggest_id)
706 suggest_id++;
707 op->suggest_id = suggest_id++;
708 GNUNET_assert (NULL != op->timeout_task);
709 GNUNET_SCHEDULER_cancel (op->timeout_task);
710 op->timeout_task = NULL;
713 op->context_msg);
714 GNUNET_log (
716 "Suggesting incoming request with accept id %u to listener %p of client %p\n",
717 op->suggest_id,
718 listener,
719 listener->cs);
720 cmsg->accept_id = htonl (op->suggest_id);
721 cmsg->peer_id = op->peer;
722 GNUNET_MQ_send (listener->cs->mq, env);
723 /* NOTE: GNUNET_CADET_receive_done() will be called in
724 #handle_client_accept() */
725}
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static uint32_t suggest_id
Counter for allocating unique IDs for clients, used to identify incoming operation requests from remo...
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
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:305
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct.
#define GNUNET_MESSAGE_TYPE_SET_REQUEST
Notify the client of a request from a remote peer.
A request for an operation with another client.
Definition: set.h:153
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: set.h:168
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: set.h:163
struct ClientState * cs
Client that owns the listener.

References GNUNET_SET_RequestMessage::accept_id, Listener::cs, 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(), ClientState::mq, msg, op, GNUNET_SET_RequestMessage::peer_id, and suggest_id.

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 735 of file gnunet-service-set.c.

736{
737 struct GNUNET_SET_Element el;
738 struct ElementEntry *ee;
739 struct GNUNET_HashCode hash;
740
742 el.size = ntohs (msg->header.size) - sizeof(*msg);
743 el.data = &msg[1];
744 el.element_type = ntohs (msg->element_type);
745 GNUNET_SET_element_hash (&el, &hash);
747 if (NULL == ee)
748 {
750 "Client inserts element %s of size %u\n",
751 GNUNET_h2s (&hash),
752 el.size);
753 ee = GNUNET_malloc (el.size + sizeof(*ee));
754 ee->element.size = el.size;
755 GNUNET_memcpy (&ee[1], el.data, el.size);
756 ee->element.data = &ee[1];
757 ee->element.element_type = el.element_type;
758 ee->remote = GNUNET_NO;
759 ee->mutations = NULL;
760 ee->mutations_size = 0;
761 ee->element_hash = hash;
764 set->content->elements,
765 &ee->element_hash,
766 ee,
768 }
769 else if (GNUNET_YES ==
774 {
776 "Client inserted element %s of size %u twice (ignored)\n",
777 GNUNET_h2s (&hash),
778 el.size);
779
780 /* same element inserted twice */
781 return;
782 }
783
784 {
785 struct MutationEvent mut = { .generation = set->current_generation,
786 .added = GNUNET_YES };
788 }
789 set->vt->add (set->state, ee);
790}
static struct GNUNET_IDENTITY_EgoLookup * el
Handle to identity lookup.
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.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_MESSAGE_TYPE_SET_ADD
Add element to set.
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1184
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation's set.
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_HashCode element_hash
Hash of the element.
A 512-bit hashcode.
Element stored in a set.
uint16_t size
Number of bytes in the buffer pointed to by data.
const void * data
Actual data of the element.
uint16_t element_type
Application-specific element type.
SetAddRemoveImpl add
Callback for element insertion.
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...

References SetVT::add, Set::content, Set::current_generation, GNUNET_SET_Element::data, el, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_Element::element_type, SetContent::elements, Set::excluded_generations, Set::excluded_generations_size, 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, is_element_of_generation(), msg, ElementEntry::mutations, ElementEntry::mutations_size, ElementEntry::remote, GNUNET_MessageHeader::size, GNUNET_SET_Element::size, Set::state, GNUNET_MessageHeader::type, and Set::vt.

Referenced by execute_mutation().

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 800 of file gnunet-service-set.c.

801{
802 struct GNUNET_SET_Element el;
803 struct ElementEntry *ee;
804 struct GNUNET_HashCode hash;
805
807 el.size = ntohs (msg->header.size) - sizeof(*msg);
808 el.data = &msg[1];
809 el.element_type = ntohs (msg->element_type);
810 GNUNET_SET_element_hash (&el, &hash);
812 if (NULL == ee)
813 {
814 /* Client tried to remove non-existing element. */
816 "Client removes non-existing element of size %u\n",
817 el.size);
818 return;
819 }
824 {
825 /* Client tried to remove element twice */
827 "Client removed element of size %u twice (ignored)\n",
828 el.size);
829 return;
830 }
831 else
832 {
833 struct MutationEvent mut = { .generation = set->current_generation,
834 .added = GNUNET_NO };
835
837 "Client removes element of size %u\n",
838 el.size);
839
841 }
842 set->vt->remove (set->state, ee);
843}
#define GNUNET_MESSAGE_TYPE_SET_REMOVE
Remove element from set.
SetAddRemoveImpl remove
Callback for element removal.

References Set::content, Set::current_generation, el, SetContent::elements, Set::excluded_generations, Set::excluded_generations_size, 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(), is_element_of_generation(), msg, ElementEntry::mutations, ElementEntry::mutations_size, SetVT::remove, GNUNET_MessageHeader::size, Set::state, GNUNET_MessageHeader::type, and Set::vt.

Referenced by execute_mutation().

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 853 of file gnunet-service-set.c.

854{
855 switch (ntohs (msg->header.type))
856 {
858 execute_add (set, msg);
859 break;
860
862 execute_remove (set, msg);
863 break;
864
865 default:
866 GNUNET_break (0);
867 }
868}
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.

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

Referenced by execute_delayed_mutations(), and handle_client_mutation().

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 878 of file gnunet-service-set.c.

879{
880 struct PendingMutation *pm;
881
882 if (0 != set->content->iterator_count)
883 return; /* still cannot do this */
884 while (NULL != (pm = set->content->pending_mutations_head))
885 {
888 pm);
890 "Executing pending mutation on %p.\n",
891 pm->set);
892 execute_mutation (pm->set, pm->msg);
893 GNUNET_free (pm->msg);
894 GNUNET_free (pm);
895 }
896}
static void execute_mutation(struct Set *set, const struct GNUNET_SET_ElementMessage *msg)
Perform a mutation on a set as specified by the msg.
int iterator_count
Number of concurrently active iterators.

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

Referenced by send_client_element().

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 913 of file gnunet-service-set.c.

914{
915 int ret;
916 struct ElementEntry *ee;
917 struct GNUNET_MQ_Envelope *ev;
919
920 GNUNET_assert (NULL != set->iter);
921 do
922 {
924 NULL,
925 (const void **) &ee);
926 if (GNUNET_NO == ret)
927 {
928 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration on %p done.\n", set);
931 set->iter = NULL;
932 set->iteration_id++;
934 set->content->iterator_count--;
936 GNUNET_MQ_send (set->cs->mq, ev);
937 return;
938 }
939 GNUNET_assert (NULL != ee);
940 }
941 while (GNUNET_NO ==
943 set->iter_generation,
947 "Sending iteration element on %p.\n",
948 set);
950 ee->element.size,
952 GNUNET_memcpy (&msg[1], ee->element.data, ee->element.size);
953 msg->element_type = htons (ee->element.element_type);
954 msg->iteration_id = htons (set->iteration_id);
955 GNUNET_MQ_send (set->cs->mq, ev);
956}
static int ret
Final status code.
Definition: gnunet-arm.c:93
static void execute_delayed_mutations(struct Set *set)
Execute mutations that were delayed on a set because of pending operations.
enum GNUNET_GenericReturnValue 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's position.
#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:61
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:85
#define GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT
Element result for the iterating client.
#define GNUNET_MESSAGE_TYPE_SET_ITER_DONE
Iteration end marker for the client.
Set element transmitted by service to client in response to a set iteration request.
Definition: set.h:325
unsigned int iter_generation
Generation we're currently iteration over.

References Set::content, Set::cs, GNUNET_SET_Element::data, ElementEntry::element, GNUNET_SET_Element::element_type, Set::excluded_generations, Set::excluded_generations_size, 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(), Set::iter, Set::iter_generation, Set::iteration_id, SetContent::iterator_count, ClientState::mq, msg, ret, and GNUNET_SET_Element::size.

Referenced by handle_client_iter_ack(), and handle_client_iterate().

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 969 of file gnunet-service-set.c.

970{
971 struct ClientState *cs = cls;
972 struct Set *set;
973
974 if (NULL == (set = cs->set))
975 {
976 /* attempt to iterate over a non existing set */
977 GNUNET_break (0);
979 return;
980 }
981 if (NULL != set->iter)
982 {
983 /* Only one concurrent iterate-action allowed per set */
984 GNUNET_break (0);
986 return;
987 }
989 "Iterating set %p in gen %u with %u content elements\n",
990 (void *) set,
991 set->current_generation,
992 GNUNET_CONTAINER_multihashmap_size (set->content->elements));
994 set->content->iterator_count++;
995 set->iter =
996 GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
997 set->iter_generation = set->current_generation;
999}
static void send_client_element(struct Set *set)
Send the next element of a set to the set's 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.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2418
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2389

References ClientState::client, Set::content, Set::cs, Set::current_generation, SetContent::elements, 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(), Set::iter, Set::iter_generation, SetContent::iterator_count, send_client_element(), and ClientState::set.

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
msgmessage sent by the client

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

1012{
1013 struct ClientState *cs = cls;
1014 struct Set *set;
1015
1017 "Client created new set (operation %u)\n",
1018 (uint32_t) ntohl (msg->operation));
1019 if (NULL != cs->set)
1020 {
1021 /* There can only be one set per client */
1022 GNUNET_break (0);
1024 return;
1025 }
1026 set = GNUNET_new (struct Set);
1027 switch (ntohl (msg->operation))
1028 {
1030 set->vt = _GSS_intersection_vt ();
1031 break;
1032
1034 set->vt = _GSS_union_vt ();
1035 break;
1036
1037 default:
1038 GNUNET_free (set);
1039 GNUNET_break (0);
1041 return;
1042 }
1043 set->operation = ntohl (msg->operation);
1044 set->state = set->vt->create ();
1045 if (NULL == set->state)
1046 {
1047 /* initialization failed (i.e. out of memory) */
1048 GNUNET_free (set);
1050 return;
1051 }
1052 set->content = GNUNET_new (struct SetContent);
1053 set->content->refcount = 1;
1055 set->cs = cs;
1056 cs->set = set;
1058}
const struct SetVT * _GSS_intersection_vt(void)
Get the table with implementing functions for set intersection.
const struct SetVT * _GSS_union_vt(void)
Get the table with implementing functions for set union.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_SET_OPERATION_INTERSECTION
Set intersection, only return elements that are in both sets.
@ GNUNET_SET_OPERATION_UNION
Set union, return all elements that are in at least one of the sets.
SetCreateImpl create
Callback for the set creation.
enum GNUNET_SET_OperationType operation
Type of operation supported for this set.

References _GSS_intersection_vt(), _GSS_union_vt(), ClientState::client, Set::content, SetVT::create, Set::cs, SetContent::elements, 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, msg, Set::operation, SetContent::refcount, ClientState::set, Set::state, and Set::vt.

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

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

1071{
1072 struct Operation *op = cls;
1073
1074 op->timeout_task = NULL;
1076 "Remote peer's incoming request timed out\n");
1078}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, incoming_destroy(), and op.

Referenced by channel_new_cb().

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 1098 of file gnunet-service-set.c.

1101{
1102 struct Listener *listener = cls;
1103 struct Operation *op;
1104
1105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New incoming channel\n");
1106 op = GNUNET_new (struct Operation);
1107 op->listener = listener;
1108 op->peer = *source;
1109 op->channel = channel;
1110 op->mq = GNUNET_CADET_get_mq (op->channel);
1114 op);
1116 return op;
1117}
static GstElement * source
Appsrc instance into which we write data for the pipeline.
#define INCOMING_CHANNEL_TIMEOUT
How long do we hold on to an incoming channel if there is no local listener before giving up?
static void incoming_timeout_cb(void *cls)
Timeout happens iff:
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition: cadet_api.c:1081
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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:1277
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct Listener * listener
Port this operation runs on.

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, op, Listener::op_head, Listener::op_tail, and source.

Referenced by handle_client_listen().

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 1137 of file gnunet-service-set.c.

1138{
1139 struct Operation *op = channel_ctx;
1140
1141 op->channel = NULL;
1143}

References _GSS_operation_destroy2(), and op.

Referenced by handle_client_evaluate(), and handle_client_listen().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_operation_destroy2()

static 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 1152 of file gnunet-service-set.c.

1153{
1154 struct GNUNET_CADET_Channel *channel;
1155
1156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "channel_end_cb called\n");
1157 if (NULL != (channel = op->channel))
1158 {
1159 /* This will free op; called conditionally as this helper function
1160 is also called from within the channel disconnect handler. */
1161 op->channel = NULL;
1163 }
1164 if (NULL != op->listener)
1165 {
1167 return;
1168 }
1169 if (NULL != op->set)
1170 op->set->vt->channel_death (op);
1171 else
1173 GNUNET_free (op);
1174}

References _GSS_operation_destroy(), GNUNET_CADET_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_YES, incoming_destroy(), and op.

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

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 1192 of file gnunet-service-set.c.

1195{
1196 /* FIXME: not implemented, we could do flow control here... */
1197}

Referenced by handle_client_evaluate(), and handle_client_listen().

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 1207 of file gnunet-service-set.c.

1208{
1209 struct ClientState *cs = cls;
1210 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1211 { GNUNET_MQ_hd_var_size (incoming_msg,
1214 NULL),
1215 GNUNET_MQ_hd_var_size (union_p2p_ibf,
1217 struct IBFMessage,
1218 NULL),
1219 GNUNET_MQ_hd_var_size (union_p2p_elements,
1222 NULL),
1223 GNUNET_MQ_hd_var_size (union_p2p_offer,
1225 struct GNUNET_MessageHeader,
1226 NULL),
1227 GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1229 struct InquiryMessage,
1230 NULL),
1231 GNUNET_MQ_hd_var_size (union_p2p_demand,
1233 struct GNUNET_MessageHeader,
1234 NULL),
1235 GNUNET_MQ_hd_fixed_size (union_p2p_done,
1237 struct GNUNET_MessageHeader,
1238 NULL),
1239 GNUNET_MQ_hd_fixed_size (union_p2p_over,
1241 struct GNUNET_MessageHeader,
1242 NULL),
1243 GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1245 struct GNUNET_MessageHeader,
1246 NULL),
1247 GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1249 struct GNUNET_MessageHeader,
1250 NULL),
1251 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1254 NULL),
1255 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1258 NULL),
1259 GNUNET_MQ_hd_var_size (union_p2p_full_element,
1262 NULL),
1263 GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1266 NULL),
1267 GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1269 struct BFMessage,
1270 NULL),
1271 GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1274 NULL),
1276 struct Listener *listener;
1277
1278 if (NULL != cs->listener)
1279 {
1280 /* max. one active listener per client! */
1281 GNUNET_break (0);
1283 return;
1284 }
1285 listener = GNUNET_new (struct Listener);
1286 listener->cs = cs;
1287 cs->listener = listener;
1288 listener->app_id = msg->app_id;
1289 listener->operation = ntohl (msg->operation);
1292 "New listener created (op %u, port %s)\n",
1293 listener->operation,
1294 GNUNET_h2s (&listener->app_id));
1296 &msg->app_id,
1298 listener,
1301 cadet_handlers);
1303}
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.
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.
static void channel_end_cb(void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
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 incoming MQ-based channels.
Definition: cadet_api.c:966
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY
Tell the other peer to send us a list of hashes that match an IBF key.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE
Strata estimator.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF
Invertible bloom filter.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
Set operation is done.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC
Compressed strata estimator.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we're sending the full set.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
Actual set elements.
#define GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST
Request a set operation from a remote peer.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE
Intersection operation is done.
#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 ...
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO
Information about the element count for intersection.
#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 ...
#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF
Bloom filter message for intersection exchange started by Bob.
Bloom filter messages exchanged for set intersection calculation.
Message handler for a specific message type.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:281
Message containing buckets of an invertible bloom filter.
estimate_best_mode_of_operation (uint64_t avg_element_size, uint64_t local_set_size,...
Last message, send to confirm the final set.
During intersection, the first (and possibly second) message send it the number of elements in the se...
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Strata estimator together with the peer's overall set size.

References Listener::app_id, cadet, 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_head, listener_tail, msg, Listener::open_port, and Listener::operation.

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 1314 of file gnunet-service-set.c.

1315{
1316 struct ClientState *cs = cls;
1317 struct Operation *op;
1318
1319 op = get_incoming (ntohl (msg->accept_reject_id));
1320 if (NULL == op)
1321 {
1322 /* no matching incoming operation for this reject;
1323 could be that the other peer already disconnected... */
1325 "Client rejected unknown operation %u\n",
1326 (unsigned int) ntohl (msg->accept_reject_id));
1328 return;
1329 }
1331 "Peer request (op %u, app %s) rejected by client\n",
1332 op->listener->operation,
1333 GNUNET_h2s (&cs->listener->app_id));
1336}
static struct Operation * get_incoming(uint32_t id)
Get the incoming socket associated with the given id.

References _GSS_operation_destroy2(), 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, msg, and op.

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 1346 of file gnunet-service-set.c.

1347{
1348 /* NOTE: Technically, we should probably check with the
1349 block library whether the element we are given is well-formed */
1350 return GNUNET_OK;
1351}

References GNUNET_OK.

◆ 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 1361 of file gnunet-service-set.c.

1362{
1363 struct ClientState *cs = cls;
1364 struct Set *set;
1365
1366 if (NULL == (set = cs->set))
1367 {
1368 /* client without a set requested an operation */
1369 GNUNET_break (0);
1371 return;
1372 }
1374
1375 if (0 != set->content->iterator_count)
1376 {
1377 struct PendingMutation *pm;
1378
1379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduling mutation on set\n");
1380 pm = GNUNET_new (struct PendingMutation);
1381 pm->msg =
1383 pm->set = set;
1386 pm);
1387 return;
1388 }
1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing mutation on set\n");
1390 execute_mutation (set, msg);
1391}
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.

References ClientState::client, Set::content, Set::cs, 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(), SetContent::iterator_count, msg, SetContent::pending_mutations_head, SetContent::pending_mutations_tail, pm, and ClientState::set.

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 1401 of file gnunet-service-set.c.

1402{
1403 struct GenerationRange r;
1404
1406 {
1407 set->content->latest_generation++;
1408 set->current_generation++;
1409 return;
1410 }
1411
1413
1414 r.start = set->current_generation + 1;
1415 r.end = set->content->latest_generation + 1;
1416 set->content->latest_generation = r.end;
1417 set->current_generation = r.end;
1420 r);
1421}
unsigned int latest_generation
FIXME: document!

References Set::content, Set::current_generation, GenerationRange::end, Set::excluded_generations, Set::excluded_generations_size, GNUNET_array_append, GNUNET_assert, SetContent::latest_generation, and GenerationRange::start.

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

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 1434 of file gnunet-service-set.c.

1435{
1436 /* FIXME: suboptimal, even if the context below could be NULL,
1437 there are malformed messages this does not check for... */
1438 return GNUNET_OK;
1439}

References GNUNET_OK.

◆ 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 1451 of file gnunet-service-set.c.

1452{
1453 struct ClientState *cs = cls;
1454 struct Operation *op = GNUNET_new (struct Operation);
1455 const struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1456 { GNUNET_MQ_hd_var_size (incoming_msg,
1459 op),
1460 GNUNET_MQ_hd_var_size (union_p2p_ibf,
1462 struct IBFMessage,
1463 op),
1464 GNUNET_MQ_hd_var_size (union_p2p_elements,
1467 op),
1468 GNUNET_MQ_hd_var_size (union_p2p_offer,
1470 struct GNUNET_MessageHeader,
1471 op),
1472 GNUNET_MQ_hd_var_size (union_p2p_inquiry,
1474 struct InquiryMessage,
1475 op),
1476 GNUNET_MQ_hd_var_size (union_p2p_demand,
1478 struct GNUNET_MessageHeader,
1479 op),
1480 GNUNET_MQ_hd_fixed_size (union_p2p_done,
1482 struct GNUNET_MessageHeader,
1483 op),
1484 GNUNET_MQ_hd_fixed_size (union_p2p_over,
1486 struct GNUNET_MessageHeader,
1487 op),
1488 GNUNET_MQ_hd_fixed_size (union_p2p_full_done,
1490 struct GNUNET_MessageHeader,
1491 op),
1492 GNUNET_MQ_hd_fixed_size (union_p2p_request_full,
1494 struct GNUNET_MessageHeader,
1495 op),
1496 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1499 op),
1500 GNUNET_MQ_hd_var_size (union_p2p_strata_estimator,
1503 op),
1504 GNUNET_MQ_hd_var_size (union_p2p_full_element,
1507 op),
1508 GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1511 op),
1512 GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1514 struct BFMessage,
1515 op),
1516 GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1519 op),
1521 struct Set *set;
1522 const struct GNUNET_MessageHeader *context;
1523
1524 if (NULL == (set = cs->set))
1525 {
1526 GNUNET_break (0);
1527 GNUNET_free (op);
1529 return;
1530 }
1532 op->peer = msg->target_peer;
1533 op->result_mode = ntohl (msg->result_mode);
1534 op->client_request_id = ntohl (msg->request_id);
1535 op->byzantine = msg->byzantine;
1536 op->byzantine_lower_bound = msg->byzantine_lower_bound;
1537 op->force_full = msg->force_full;
1538 op->force_delta = msg->force_delta;
1540
1541 /* Advance generation values, so that
1542 mutations won't interfer with the running operation. */
1543 op->set = set;
1544 op->generation_created = set->current_generation;
1545 advance_generation (set);
1548 "Creating new CADET channel to port %s for set operation type %u\n",
1549 GNUNET_h2s (&msg->app_id),
1550 set->operation);
1552 op,
1553 &msg->target_peer,
1554 &msg->app_id,
1557 cadet_handlers);
1558 op->mq = GNUNET_CADET_get_mq (op->channel);
1559 op->state = set->vt->evaluate (op, context);
1560 if (NULL == op->state)
1561 {
1562 GNUNET_break (0);
1564 return;
1565 }
1567}
static pa_context * context
Pulseaudio context.
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
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:1030
OpEvaluateImpl evaluate
Callback for starting evaluation with a remote peer.

References advance_generation(), cadet, channel_end_cb(), channel_window_cb(), ClientState::client, context, Set::current_generation, SetVT::evaluate, 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(), msg, op, Set::operation, Set::ops_head, Set::ops_tail, ClientState::set, and Set::vt.

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 1579 of file gnunet-service-set.c.

1580{
1581 struct ClientState *cs = cls;
1582 struct Set *set;
1583
1584 if (NULL == (set = cs->set))
1585 {
1586 /* client without a set acknowledged receiving a value */
1587 GNUNET_break (0);
1589 return;
1590 }
1591 if (NULL == set->iter)
1592 {
1593 /* client sent an ack, but we were not expecting one (as
1594 set iteration has finished) */
1595 GNUNET_break (0);
1597 return;
1598 }
1600 if (ntohl (ack->send_more))
1601 {
1602 send_client_element (set);
1603 }
1604 else
1605 {
1607 set->iter = NULL;
1608 set->iteration_id++;
1609 }
1610}
uint32_t send_more
Non-zero if the service should continue sending elements.
Definition: set.h:360

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

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 1620 of file gnunet-service-set.c.

1622{
1623 struct ClientState *cs = cls;
1624 struct Set *set;
1625 struct LazyCopyRequest *cr;
1626 struct GNUNET_MQ_Envelope *ev;
1627 struct GNUNET_SET_CopyLazyResponseMessage *resp_msg;
1628
1629 if (NULL == (set = cs->set))
1630 {
1631 /* client without a set requested an operation */
1632 GNUNET_break (0);
1634 return;
1635 }
1637 "Client requested creation of lazy copy\n");
1638 cr = GNUNET_new (struct LazyCopyRequest);
1639 cr->cookie = ++lazy_copy_cookie;
1640 cr->source_set = set;
1643 resp_msg->cookie = cr->cookie;
1644 GNUNET_MQ_send (set->cs->mq, ev);
1646}
static uint32_t lazy_copy_cookie
Generator for unique cookie we set per lazy copy request.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:76
#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE
Give the client an ID for connecting to the set's copy.
Server responds to a lazy copy request.
Definition: set.h:368
uint32_t cookie
Temporary name for the copied set.
Definition: set.h:377
uint32_t cookie
Cookie identifying the request.

References ClientState::client, LazyCopyRequest::cookie, GNUNET_SET_CopyLazyResponseMessage::cookie, Set::cs, 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, lazy_copy_head, lazy_copy_tail, ClientState::mq, ClientState::set, and LazyCopyRequest::source_set.

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 1656 of file gnunet-service-set.c.

1659{
1660 struct ClientState *cs = cls;
1661 struct LazyCopyRequest *cr;
1662 struct Set *set;
1663 int found;
1664
1665 if (NULL != cs->set)
1666 {
1667 /* There can only be one set per client */
1668 GNUNET_break (0);
1670 return;
1671 }
1672 found = GNUNET_NO;
1673 for (cr = lazy_copy_head; NULL != cr; cr = cr->next)
1674 {
1675 if (cr->cookie == msg->cookie)
1676 {
1677 found = GNUNET_YES;
1678 break;
1679 }
1680 }
1681 if (GNUNET_NO == found)
1682 {
1683 /* client asked for copy with cookie we don't know */
1684 GNUNET_break (0);
1686 return;
1687 }
1690 "Client %p requested use of lazy copy\n",
1691 cs);
1692 set = GNUNET_new (struct Set);
1693 switch (cr->source_set->operation)
1694 {
1696 set->vt = _GSS_intersection_vt ();
1697 break;
1698
1700 set->vt = _GSS_union_vt ();
1701 break;
1702
1703 default:
1704 GNUNET_assert (0);
1705 return;
1706 }
1707
1708 if (NULL == set->vt->copy_state)
1709 {
1710 /* Lazy copy not supported for this set operation */
1711 GNUNET_break (0);
1712 GNUNET_free (set);
1713 GNUNET_free (cr);
1715 return;
1716 }
1717
1718 set->operation = cr->source_set->operation;
1719 set->state = set->vt->copy_state (cr->source_set->state);
1720 set->content = cr->source_set->content;
1721 set->content->refcount++;
1722
1728 * sizeof(struct GenerationRange));
1729
1730 /* Advance the generation of the new set, so that mutations to the
1731 of the cloned set and the source set are independent. */
1732 advance_generation (set);
1733 set->cs = cs;
1734 cs->set = set;
1735 GNUNET_free (cr);
1737}
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
SetCopyStateImpl copy_state
Callback for making a copy of a set's internal state.

References _GSS_intersection_vt(), _GSS_union_vt(), advance_generation(), ClientState::client, Set::content, LazyCopyRequest::cookie, SetVT::copy_state, 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, lazy_copy_head, lazy_copy_tail, msg, LazyCopyRequest::next, Set::operation, SetContent::refcount, ClientState::set, LazyCopyRequest::source_set, Set::state, and Set::vt.

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 1747 of file gnunet-service-set.c.

1748{
1749 struct ClientState *cs = cls;
1750 struct Set *set;
1751 struct Operation *op;
1752 int found;
1753
1754 if (NULL == (set = cs->set))
1755 {
1756 /* client without a set requested an operation */
1757 GNUNET_break (0);
1759 return;
1760 }
1761 found = GNUNET_NO;
1762 for (op = set->ops_head; NULL != op; op = op->next)
1763 {
1764 if (op->client_request_id == ntohl (msg->request_id))
1765 {
1766 found = GNUNET_YES;
1767 break;
1768 }
1769 }
1770 if (GNUNET_NO == found)
1771 {
1772 /* It may happen that the operation was already destroyed due to
1773 * the other peer disconnecting. The client may not know about this
1774 * yet and try to cancel the (just barely non-existent) operation.
1775 * So this is not a hard error.
1777 "Client canceled non-existent op %u\n",
1778 (uint32_t) ntohl (msg->request_id));
1779 }
1780 else
1781 {
1783 "Client requested cancel for op %u\n",
1784 (uint32_t) ntohl (msg->request_id));
1786 }
1788}
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set.

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

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 1800 of file gnunet-service-set.c.

1801{
1802 struct ClientState *cs = cls;
1803 struct Set *set;
1804 struct Operation *op;
1805 struct GNUNET_SET_ResultMessage *result_message;
1806 struct GNUNET_MQ_Envelope *ev;
1807 struct Listener *listener;
1808
1809 if (NULL == (set = cs->set))
1810 {
1811 /* client without a set requested to accept */
1812 GNUNET_break (0);
1814 return;
1815 }
1816 op = get_incoming (ntohl (msg->accept_reject_id));
1817 if (NULL == op)
1818 {
1819 /* It is not an error if the set op does not exist -- it may
1820 * have been destroyed when the partner peer disconnected. */
1821 GNUNET_log (
1823 "Client %p accepted request %u of listener %p that is no longer active\n",
1824 cs,
1825 ntohl (msg->accept_reject_id),
1826 cs->listener);
1827 ev = GNUNET_MQ_msg (result_message, GNUNET_MESSAGE_TYPE_SET_RESULT);
1828 result_message->request_id = msg->request_id;
1829 result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE);
1830 GNUNET_MQ_send (set->cs->mq, ev);
1832 return;
1833 }
1835 "Client accepting request %u\n",
1836 (uint32_t) ntohl (msg->accept_reject_id));
1837 listener = op->listener;
1838 op->listener = NULL;
1839 GNUNET_CONTAINER_DLL_remove (listener->op_head, listener->op_tail, op);
1840 op->set = set;
1842 op->client_request_id = ntohl (msg->request_id);
1843 op->result_mode = ntohl (msg->result_mode);
1844 op->byzantine = msg->byzantine;
1845 op->byzantine_lower_bound = msg->byzantine_lower_bound;
1846 op->force_full = msg->force_full;
1847 op->force_delta = msg->force_delta;
1848
1849 /* Advance generation values, so that future mutations do not
1850 interfer with the running operation. */
1851 op->generation_created = set->current_generation;
1852 advance_generation (set);
1853 GNUNET_assert (NULL == op->state);
1854 op->state = set->vt->accept (op);
1855 if (NULL == op->state)
1856 {
1857 GNUNET_break (0);
1859 return;
1860 }
1861 /* Now allow CADET to continue, as we did not do this in
1862 #handle_incoming_msg (as we wanted to first see if the
1863 local client would accept the request). */
1864 GNUNET_CADET_receive_done (op->channel);
1866}
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:875
#define GNUNET_MESSAGE_TYPE_SET_RESULT
Create an empty set.
@ GNUNET_SET_STATUS_FAILURE
The other peer refused to to the operation with us, or something went wrong.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: set.h:245
uint32_t request_id
id the result belongs to
Definition: set.h:259
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SET_Status in NBO.
Definition: set.h:265
OpAcceptImpl accept
Callback for accepting a set operation request.

References SetVT::accept, advance_generation(), ClientState::client, Listener::cs, Set::cs, Set::current_generation, 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, ClientState::mq, msg, op, Listener::op_head, Listener::op_tail, Set::ops_head, Set::ops_tail, GNUNET_SET_ResultMessage::request_id, GNUNET_SET_ResultMessage::result_status, ClientState::set, and Set::vt.

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 1875 of file gnunet-service-set.c.

1876{
1877 /* Delay actual shutdown to allow service to disconnect clients */
1879 if (0 == num_clients)
1880 {
1881 if (NULL != cadet)
1882 {
1884 cadet = NULL;
1885 }
1886 }
1888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handled shutdown request\n");
1889}
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

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

Referenced by run().

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 1901 of file gnunet-service-set.c.

1904{
1905 /* FIXME: need to modify SERVICE (!) API to allow
1906 us to run a shutdown task *after* clients were
1907 forcefully disconnected! */
1911 if (NULL == cadet)
1912 {
1914 _ ("Could not connect to CADET service\n"));
1916 return;
1917 }
1918}
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
static void shutdown_task(void *cls)
Called to clean up, after a shutdown has been requested.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:897
@ GNUNET_ERROR_TYPE_ERROR
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
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,...
Definition: scheduler.c:1339
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178

References _, _GSS_statistics, cadet, cfg, GNUNET_CADET_connect(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), and shutdown_task().

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( GNUNET_OS_project_data_gnunet()  ,
"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.

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 125 of file gnunet-service-set.c.

Referenced by client_disconnect_cb(), handle_client_evaluate(), handle_client_listen(), run(), and shutdown_task().

◆ lazy_copy_head

struct LazyCopyRequest* lazy_copy_head
static

DLL of lazy copy requests by this client.

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

Referenced by client_disconnect_cb(), handle_client_copy_lazy_connect(), and handle_client_copy_lazy_prepare().

◆ lazy_copy_tail

struct LazyCopyRequest* lazy_copy_tail
static

DLL of lazy copy requests by this client.

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

Referenced by client_disconnect_cb(), handle_client_copy_lazy_connect(), and handle_client_copy_lazy_prepare().

◆ lazy_copy_cookie

uint32_t lazy_copy_cookie
static

Generator for unique cookie we set per lazy copy request.

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

Referenced by handle_client_copy_lazy_prepare().

◆ _GSS_statistics

◆ listener_head

struct Listener* listener_head
static

Listeners are held in a doubly linked list.

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

Referenced by client_disconnect_cb(), get_incoming(), and handle_client_listen().

◆ listener_tail

struct Listener* listener_tail
static

Listeners are held in a doubly linked list.

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

Referenced by client_disconnect_cb(), and handle_client_listen().

◆ num_clients

unsigned int num_clients
static

Number of active clients.

Definition at line 160 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 166 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 174 of file gnunet-service-set.c.

Referenced by handle_incoming_msg().