GNUnet  0.11.x
Data Structures | Macros | Enumerations | Functions | Variables
gnunet-service-seti.c File Reference
#include "gnunet-service-seti_protocol.h"
#include "gnunet_statistics_service.h"
#include "gnunet_cadet_service.h"
#include "gnunet_seti_service.h"
#include "gnunet_block_lib.h"
#include "seti.h"
Include dependency graph for gnunet-service-seti.c:

Go to the source code of this file.

Data Structures

struct  ElementEntry
 Information about an element element in the set. More...
 
struct  ClientState
 State we keep per client. More...
 
struct  Operation
 Operation context used to execute a set operation. More...
 
struct  SetContent
 SetContent stores the actual set elements, which may be shared by multiple generations derived from one set. More...
 
struct  Set
 A set that supports a specific operation with other peers. More...
 
struct  Listener
 A listener is inhabited by a client, and waits for evaluation requests from remote peers. 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...
 

Enumerations

enum  IntersectionOperationPhase {
  PHASE_INITIAL, PHASE_COUNT_SENT, PHASE_BF_EXCHANGE, PHASE_MUST_SEND_DONE,
  PHASE_DONE_RECEIVED, PHASE_FINISHED, PHASE_INITIAL, PHASE_COUNT_SENT,
  PHASE_BF_EXCHANGE, PHASE_MUST_SEND_DONE, PHASE_DONE_RECEIVED, PHASE_FINISHED
}
 Current phase we are in for a intersection operation. More...
 

Functions

static void send_client_removed_element (struct Operation *op, struct GNUNET_SETI_Element *element)
 If applicable in the current operation mode, send a result message to the client indicating we removed an element. More...
 
static int _GSS_is_element_of_operation (struct ElementEntry *ee, struct Operation *op)
 Is element ee part of the set used by op? More...
 
static int filtered_map_initialization (void *cls, const struct GNUNET_HashCode *key, void *value)
 Fills the "my_elements" hashmap with all relevant elements. More...
 
static int iterator_bf_reduce (void *cls, const struct GNUNET_HashCode *key, void *value)
 Removes elements from our hashmap if they are not contained within the provided remote bloomfilter. More...
 
static int iterator_bf_create (void *cls, const struct GNUNET_HashCode *key, void *value)
 Create initial bloomfilter based on all the elements given. More...
 
static void _GSS_operation_destroy (struct Operation *op)
 Destroy the given operation. More...
 
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. More...
 
static void incoming_destroy (struct Operation *op)
 Destroy an incoming request from a remote peer. More...
 
static void send_client_done_and_destroy (void *cls)
 Signal to the client that the operation has finished and destroy the operation. More...
 
static void fail_intersection_operation (struct Operation *op)
 Inform the client that the intersection operation has failed, and proceed to destroy the evaluate operation. More...
 
static void send_bloomfilter (struct Operation *op)
 Send a bloomfilter to our peer. More...
 
static void finished_local_operations (void *cls)
 Remember that we are done dealing with the local client AND have sent the other peer our message that we are done, so we are not just waiting for the channel to die before telling the local client that we are done as our last act. More...
 
static void send_p2p_done (struct Operation *op)
 Notify the other peer that we are done. More...
 
static void send_remaining_elements (void *cls)
 Send all elements in the full result iterator. More...
 
static int initialize_map_unfiltered (void *cls, const struct GNUNET_HashCode *key, void *value)
 Fills the "my_elements" hashmap with the initial set of (non-deleted) elements from the set of the specification. More...
 
static void send_element_count (struct Operation *op)
 Send our element count to the peer, in case our element count is lower than theirs. More...
 
static void begin_bf_exchange (struct Operation *op)
 We go first, initialize our map with all elements and send the first Bloom filter. More...
 
static void handle_intersection_p2p_element_info (void *cls, const struct IntersectionElementInfoMessage *msg)
 Handle the initial struct IntersectionElementInfoMessage from a remote peer. More...
 
static void process_bf (struct Operation *op)
 Process a Bloomfilter once we got all the chunks. More...
 
static int check_intersection_p2p_bf (void *cls, const struct BFMessage *msg)
 Check an BF message from a remote peer. More...
 
static void handle_intersection_p2p_bf (void *cls, const struct BFMessage *msg)
 Handle an BF message from a remote peer. More...
 
static int filter_all (void *cls, const struct GNUNET_HashCode *key, void *value)
 Remove all elements from our hashmap. More...
 
static void handle_intersection_p2p_done (void *cls, const struct IntersectionDoneMessage *idm)
 Handle a done message from a remote peer. More...
 
static struct Operationget_incoming (uint32_t id)
 Get the incoming socket associated with the given id. 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 handle_client_create_set (void *cls, const struct GNUNET_SETI_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...
 
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_SETI_ListenMessage *msg)
 Called when a client wants to create a new listener. More...
 
static void handle_client_reject (void *cls, const struct GNUNET_SETI_RejectMessage *msg)
 Called when the listening client rejects an operation request by another peer. More...
 
static int check_client_set_add (void *cls, const struct GNUNET_SETI_ElementMessage *msg)
 Called when a client wants to add or remove an element to a set it inhabits. More...
 
static void handle_client_set_add (void *cls, const struct GNUNET_SETI_ElementMessage *msg)
 Called when a client wants to add 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_SETI_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_SETI_EvaluateMessage *msg)
 Called when a client wants to initiate a set operation with another peer. More...
 
static void handle_client_cancel (void *cls, const struct GNUNET_SETI_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_SETI_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 ("seti", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_accept, GNUNET_MESSAGE_TYPE_SETI_ACCEPT, struct GNUNET_SETI_AcceptMessage, NULL), GNUNET_MQ_hd_var_size(client_set_add, GNUNET_MESSAGE_TYPE_SETI_ADD, struct GNUNET_SETI_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_create_set, GNUNET_MESSAGE_TYPE_SETI_CREATE, struct GNUNET_SETI_CreateMessage, NULL), GNUNET_MQ_hd_var_size(client_evaluate, GNUNET_MESSAGE_TYPE_SETI_EVALUATE, struct GNUNET_SETI_EvaluateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_listen, GNUNET_MESSAGE_TYPE_SETI_LISTEN, struct GNUNET_SETI_ListenMessage, NULL), GNUNET_MQ_hd_fixed_size(client_reject, GNUNET_MESSAGE_TYPE_SETI_REJECT, struct GNUNET_SETI_RejectMessage, NULL), GNUNET_MQ_hd_fixed_size(client_cancel, GNUNET_MESSAGE_TYPE_SETI_CANCEL, struct GNUNET_SETI_CancelMessage, 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 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...
 

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-seti.c.

Referenced by channel_new_cb().

Enumeration Type Documentation

◆ IntersectionOperationPhase

Current phase we are in for a intersection operation.

Enumerator
PHASE_INITIAL 

We are just starting.

PHASE_COUNT_SENT 

We have send the number of our elements to the other peer, but did not setup our element set yet.

PHASE_BF_EXCHANGE 

We have initialized our set and are now reducing it by exchanging Bloom filters until one party notices the their element hashes are equal.

PHASE_MUST_SEND_DONE 

We must next send the P2P DONE message (after finishing mostly with the local client).

Then we will wait for the channel to close.

PHASE_DONE_RECEIVED 

We have received the P2P DONE message, and must finish with the local client before terminating the channel.

PHASE_FINISHED 

The protocol is over.

Results may still have to be sent to the client.

PHASE_INITIAL 

We are just starting.

PHASE_COUNT_SENT 

We have send the number of our elements to the other peer, but did not setup our element set yet.

PHASE_BF_EXCHANGE 

We have initialized our set and are now reducing it by exchanging Bloom filters until one party notices the their element hashes are equal.

PHASE_MUST_SEND_DONE 

We must next send the P2P DONE message (after finishing mostly with the local client).

Then we will wait for the channel to close.

PHASE_DONE_RECEIVED 

We have received the P2P DONE message, and must finish with the local client before terminating the channel.

PHASE_FINISHED 

The protocol is over.

Results may still have to be sent to the client.

Definition at line 43 of file gnunet-service-seti.c.

44 {
49 
55 
62 
68 
74 
80 };
We are just starting.
We have send the number of our elements to the other peer, but did not setup our element set yet...
The protocol is over.
We must next send the P2P DONE message (after finishing mostly with the local client).
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
We have received the P2P DONE message, and must finish with the local client before terminating the c...

Function Documentation

◆ send_client_removed_element()

static void send_client_removed_element ( struct Operation op,
struct GNUNET_SETI_Element element 
)
static

If applicable in the current operation mode, send a result message to the client indicating we removed an element.

Parameters
opintersection operation
elementelement to send

Definition at line 516 of file gnunet-service-seti.c.

References Operation::client_request_id, Set::cs, GNUNET_SETI_Element::data, GNUNET_SETI_Element::element_type, GNUNET_SETI_ResultMessage::element_type, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETI_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SETI_STATUS_DEL_LOCAL, GNUNET_STATISTICS_update(), GNUNET_YES, ClientState::mq, GNUNET_SETI_ResultMessage::request_id, GNUNET_SETI_ResultMessage::result_status, Operation::return_intersection, Operation::set, and GNUNET_SETI_Element::size.

Referenced by filter_all(), filtered_map_initialization(), and iterator_bf_reduce().

518 {
519  struct GNUNET_MQ_Envelope *ev;
520  struct GNUNET_SETI_ResultMessage *rm;
521 
522  if (GNUNET_YES == op->return_intersection)
523  {
524  GNUNET_break (0);
525  return; /* Wrong mode for transmitting removed elements */
526  }
528  "Sending removed element (size %u) to client\n",
529  element->size);
531  "# Element removed messages sent",
532  1,
533  GNUNET_NO);
534  GNUNET_assert (0 != op->client_request_id);
535  ev = GNUNET_MQ_msg_extra (rm,
536  element->size,
538  if (NULL == ev)
539  {
540  GNUNET_break (0);
541  return;
542  }
544  rm->request_id = htonl (op->client_request_id);
545  rm->element_type = element->element_type;
546  GNUNET_memcpy (&rm[1],
547  element->data,
548  element->size);
549  GNUNET_MQ_send (op->set->cs->mq,
550  ev);
551 }
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: seti.h:191
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
uint16_t size
Number of bytes in the buffer pointed to by data.
int return_intersection
When are elements sent to the client, and which elements are sent?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
uint32_t request_id
id the result belongs to
Definition: seti.h:206
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
const void * data
Actual data of the element.
#define GNUNET_MESSAGE_TYPE_SETI_RESULT
Handle result message from operation.
struct ClientState * cs
Client that owns the set.
Element should be delete from the result set of the local peer, i.e.
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETI_Status in NBO.
Definition: seti.h:212
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint16_t element_type
Application-specific element type.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: seti.h:217
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_is_element_of_operation()

static int _GSS_is_element_of_operation ( struct ElementEntry ee,
struct Operation op 
)
static

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 562 of file gnunet-service-seti.c.

References ElementEntry::generation_added, and Operation::generation_created.

Referenced by filtered_map_initialization(), and initialize_map_unfiltered().

564 {
565  return op->generation_created >= ee->generation_added;
566 }
unsigned int generation_created
Generation in which the operation handle was created.
unsigned int generation_added
Generation in which the element was added.
Here is the caller graph for this function:

◆ filtered_map_initialization()

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

Fills the "my_elements" hashmap with all relevant elements.

Parameters
clsthe struct Operation * we are performing
keycurrent key code
valuethe struct ElementEntry * from the hash map
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 578 of file gnunet-service-seti.c.

References _GSS_is_element_of_operation(), ElementEntry::element, ElementEntry::element_hash, GNUNET_BLOCK_mingle_hash(), GNUNET_break, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, Operation::my_element_count, Operation::my_elements, Operation::my_xor, op, Operation::remote_bf, Operation::salt, send_client_removed_element(), GNUNET_SET_Element::size, and value.

Referenced by process_bf().

581 {
582  struct Operation *op = cls;
583  struct ElementEntry *ee = value;
584  struct GNUNET_HashCode mutated_hash;
585 
587  "FIMA called for %s:%u\n",
588  GNUNET_h2s (&ee->element_hash),
589  ee->element.size);
590 
591  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
592  {
594  "Reduced initialization, not starting with %s:%u (wrong generation)\n",
595  GNUNET_h2s (&ee->element_hash),
596  ee->element.size);
597  return GNUNET_YES; /* element not valid in our operation's generation */
598  }
599 
600  /* Test if element is in other peer's bloomfilter */
602  op->salt,
603  &mutated_hash);
605  "Testing mingled hash %s with salt %u\n",
606  GNUNET_h2s (&mutated_hash),
607  op->salt);
608  if (GNUNET_NO ==
610  &mutated_hash))
611  {
612  /* remove this element */
614  &ee->element);
616  "Reduced initialization, not starting with %s:%u\n",
617  GNUNET_h2s (&ee->element_hash),
618  ee->element.size);
619  return GNUNET_YES;
620  }
621  op->my_element_count++;
623  &ee->element_hash,
624  &op->my_xor);
626  "Filtered initialization of my_elements, adding %s:%u\n",
627  GNUNET_h2s (&ee->element_hash),
628  ee->element.size);
631  &ee->element_hash,
632  ee,
634 
635  return GNUNET_YES;
636 }
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_HashCode element_hash
Hash of the element.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
A 512-bit hashcode.
static void send_client_removed_element(struct Operation *op, struct GNUNET_SETI_Element *element)
If applicable in the current operation mode, send a result message to the client indicating we remove...
There must only be one value per key; storing a value should fail if a value under the same key alrea...
Operation context used to execute a set operation.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
uint32_t salt
Salt to use for the operation.
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:202
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_BLOCK_mingle_hash(const struct GNUNET_HashCode *in, uint32_t mingle_number, struct GNUNET_HashCode *hc)
Mingle hash with the mingle_number to produce different bits.
Definition: block.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ iterator_bf_reduce()

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

Removes elements from our hashmap if they are not contained within the provided remote bloomfilter.

Parameters
clsclosure with the struct Operation *
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 649 of file gnunet-service-seti.c.

References ElementEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_BLOCK_mingle_hash(), GNUNET_break, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, Operation::my_element_count, Operation::my_elements, Operation::my_xor, op, Operation::remote_bf, Operation::salt, send_client_removed_element(), GNUNET_SET_Element::size, and value.

Referenced by process_bf().

652 {
653  struct Operation *op = cls;
654  struct ElementEntry *ee = value;
655  struct GNUNET_HashCode mutated_hash;
656 
658  op->salt,
659  &mutated_hash);
661  "Testing mingled hash %s with salt %u\n",
662  GNUNET_h2s (&mutated_hash),
663  op->salt);
664  if (GNUNET_NO ==
666  &mutated_hash))
667  {
668  GNUNET_break (0 < op->my_element_count);
669  op->my_element_count--;
671  &ee->element_hash,
672  &op->my_xor);
674  "Bloom filter reduction of my_elements, removing %s:%u\n",
675  GNUNET_h2s (&ee->element_hash),
676  ee->element.size);
679  &ee->element_hash,
680  ee));
682  &ee->element);
683  }
684  else
685  {
687  "Bloom filter reduction of my_elements, keeping %s:%u\n",
688  GNUNET_h2s (&ee->element_hash),
689  ee->element.size);
690  }
691  return GNUNET_YES;
692 }
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
A 512-bit hashcode.
static void send_client_removed_element(struct Operation *op, struct GNUNET_SETI_Element *element)
If applicable in the current operation mode, send a result message to the client indicating we remove...
Operation context used to execute a set operation.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
uint32_t salt
Salt to use for the operation.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:202
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_BLOCK_mingle_hash(const struct GNUNET_HashCode *in, uint32_t mingle_number, struct GNUNET_HashCode *hc)
Mingle hash with the mingle_number to produce different bits.
Definition: block.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ iterator_bf_create()

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

Create initial bloomfilter based on all the elements given.

Parameters
clsthe struct Operation *
keycurrent key code
valuethe struct ElementEntry to process
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 704 of file gnunet-service-seti.c.

References ElementEntry::element_hash, GNUNET_BLOCK_mingle_hash(), GNUNET_CONTAINER_bloomfilter_add(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_YES, Operation::local_bf, op, Operation::salt, and value.

Referenced by send_bloomfilter().

707 {
708  struct Operation *op = cls;
709  struct ElementEntry *ee = value;
710  struct GNUNET_HashCode mutated_hash;
711 
713  op->salt,
714  &mutated_hash);
716  "Initializing BF with hash %s with salt %u\n",
717  GNUNET_h2s (&mutated_hash),
718  op->salt);
720  &mutated_hash);
721  return GNUNET_YES;
722 }
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
struct GNUNET_HashCode element_hash
Hash of the element.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static char * value
Value of the record to add/remove.
Information about an element element in the set.
A 512-bit hashcode.
Operation context used to execute a set operation.
uint32_t salt
Salt to use for the operation.
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_BLOCK_mingle_hash(const struct GNUNET_HashCode *in, uint32_t mingle_number, struct GNUNET_HashCode *hc)
Mingle hash with the mingle_number to produce different bits.
Definition: block.c:81
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _GSS_operation_destroy()

static void _GSS_operation_destroy ( struct Operation op)
static

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

Definition at line 738 of file gnunet-service-seti.c.

References _GSS_operation_destroy2(), Operation::channel, Operation::context_msg, Operation::full_result_iter, GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, Operation::listener, Operation::local_bf, Operation::my_elements, op, Operation::remote_bf, and Operation::set.

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

739 {
740  struct Set *set = op->set;
741  struct GNUNET_CADET_Channel *channel;
742 
743  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying operation %p\n", op);
744  GNUNET_assert (NULL == op->listener);
745  if (NULL != op->remote_bf)
746  {
748  op->remote_bf = NULL;
749  }
750  if (NULL != op->local_bf)
751  {
753  op->local_bf = NULL;
754  }
755  if (NULL != op->my_elements)
756  {
758  op->my_elements = NULL;
759  }
760  if (NULL != op->full_result_iter)
761  {
763  op->full_result_iter);
764  op->full_result_iter = NULL;
765  }
767  "Destroying intersection op state done\n");
768  if (NULL != set)
769  {
770  GNUNET_CONTAINER_DLL_remove (set->ops_head,
771  set->ops_tail,
772  op);
773  op->set = NULL;
774  }
775  if (NULL != op->context_msg)
776  {
777  GNUNET_free (op->context_msg);
778  op->context_msg = NULL;
779  }
780  if (NULL != (channel = op->channel))
781  {
782  /* This will free op; called conditionally as this helper function
783  is also called from within the channel disconnect handler. */
784  op->channel = NULL;
786  }
787  /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
788  * there was a channel end handler that will free 'op' on the call stack. */
789 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Opaque handle to a channel.
Definition: cadet.h:116
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
A set that supports a specific operation with other peers.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
struct Listener * listener
Port this operation runs on.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
#define GNUNET_free(ptr)
Wrapper around free.
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)
static

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 866 of file gnunet-service-seti.c.

References _GSS_operation_destroy(), Operation::channel, Operation::channel_death_expected, GNUNET_CADET_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_YES, incoming_destroy(), Operation::listener, send_client_done_and_destroy(), and Operation::set.

Referenced by _GSS_operation_destroy(), channel_end_cb(), handle_client_reject(), and incoming_destroy().

867 {
868  struct GNUNET_CADET_Channel *channel;
869 
871  "channel_end_cb called\n");
872  if (NULL != (channel = op->channel))
873  {
874  /* This will free op; called conditionally as this helper function
875  is also called from within the channel disconnect handler. */
876  op->channel = NULL;
878  }
879  if (NULL != op->listener)
880  {
881  incoming_destroy (op);
882  return;
883  }
884  if (NULL != op->set)
885  {
887  {
888  /* oh goodie, we are done! */
890  }
891  else
892  {
893  /* sorry, channel went down early, too bad. */
895  }
896  }
897  else
899  GNUNET_free (op);
900 }
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
Opaque handle to a channel.
Definition: cadet.h:116
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
struct GNUNET_CADET_Channel * channel
Channel to the peer.
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
#define GNUNET_log(kind,...)
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
struct Listener * listener
Port this operation runs on.
int channel_death_expected
Set whenever we reach the state where the death of the channel is perfectly find and should NOT resul...
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
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 807 of file gnunet-service-seti.c.

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

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

808 {
809  struct Listener *listener;
810 
812  "Destroying incoming operation %p\n",
813  op);
814  if (NULL != (listener = op->listener))
815  {
817  listener->op_tail,
818  op);
819  op->listener = NULL;
820  }
821  if (NULL != op->timeout_task)
822  {
824  op->timeout_task = NULL;
825  }
827 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
#define GNUNET_log(kind,...)
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
struct Listener * listener
Port this operation runs on.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_client_done_and_destroy()

static void send_client_done_and_destroy ( void *  cls)
static

Signal to the client that the operation has finished and destroy the operation.

Parameters
clsoperation to destroy

Definition at line 837 of file gnunet-service-seti.c.

References _GSS_operation_destroy(), Operation::client_request_id, Set::cs, GNUNET_SETI_ResultMessage::element_type, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SETI_STATUS_DONE, GNUNET_STATISTICS_update(), ClientState::mq, GNUNET_SETI_ResultMessage::request_id, GNUNET_SETI_ResultMessage::result_status, and Operation::set.

Referenced by _GSS_operation_destroy2(), handle_intersection_p2p_done(), and send_remaining_elements().

838 {
839  struct Operation *op = cls;
840  struct GNUNET_MQ_Envelope *ev;
841  struct GNUNET_SETI_ResultMessage *rm;
842 
844  "Intersection succeeded, sending DONE to local client\n");
846  "# Intersection operations succeeded",
847  1,
848  GNUNET_NO);
849  ev = GNUNET_MQ_msg (rm,
851  rm->request_id = htonl (op->client_request_id);
853  rm->element_type = htons (0);
854  GNUNET_MQ_send (op->set->cs->mq,
855  ev);
857 }
Success, all elements have been sent (and received).
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: seti.h:191
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint32_t request_id
id the result belongs to
Definition: seti.h:206
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_MESSAGE_TYPE_SETI_RESULT
Handle result message from operation.
struct ClientState * cs
Client that owns the set.
Operation context used to execute a set operation.
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETI_Status in NBO.
Definition: seti.h:212
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: seti.h:217
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fail_intersection_operation()

static void fail_intersection_operation ( struct Operation op)
static

Inform the client that the intersection operation has failed, and proceed to destroy the evaluate operation.

Parameters
opthe intersection operation to fail

Definition at line 910 of file gnunet-service-seti.c.

References _GSS_operation_destroy(), Operation::client_request_id, Set::cs, GNUNET_SETI_ResultMessage::element_type, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SETI_STATUS_FAILURE, GNUNET_STATISTICS_update(), ClientState::mq, msg, Operation::my_elements, GNUNET_SETI_ResultMessage::request_id, GNUNET_SETI_ResultMessage::result_status, and Operation::set.

Referenced by handle_intersection_p2p_bf(), handle_intersection_p2p_done(), handle_intersection_p2p_element_info(), and process_bf().

911 {
912  struct GNUNET_MQ_Envelope *ev;
914 
916  "Intersection operation failed\n");
918  "# Intersection operations failed",
919  1,
920  GNUNET_NO);
921  if (NULL != op->my_elements)
922  {
924  op->my_elements = NULL;
925  }
926  ev = GNUNET_MQ_msg (msg,
929  msg->request_id = htonl (op->client_request_id);
930  msg->element_type = htons (0);
931  GNUNET_MQ_send (op->set->cs->mq,
932  ev);
934 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: seti.h:191
The other peer refused to do the operation with us, or something went wrong.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint32_t request_id
id the result belongs to
Definition: seti.h:206
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_MESSAGE_TYPE_SETI_RESULT
Handle result message from operation.
struct ClientState * cs
Client that owns the set.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETI_Status in NBO.
Definition: seti.h:212
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: seti.h:217
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_bloomfilter()

static void send_bloomfilter ( struct Operation op)
static

Send a bloomfilter to our peer.

After the result done message has been sent to the client, destroy the evaluate operation.

Parameters
opintersection operation

Definition at line 944 of file gnunet-service-seti.c.

References BFMessage::bits_per_element, BFMessage::bloomfilter_total_length, BFMessage::element_xor_hash, GNUNET_assert, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_get_raw_data(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETI_P2P_BF, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, iterator_bf_create(), Operation::local_bf, Operation::mq, msg, Operation::my_element_count, Operation::my_elements, Operation::my_xor, Operation::remote_element_count, Operation::salt, BFMessage::sender_element_count, and BFMessage::sender_mutator.

Referenced by begin_bf_exchange(), and process_bf().

945 {
946  struct GNUNET_MQ_Envelope *ev;
947  struct BFMessage *msg;
948  uint32_t bf_size;
949  uint32_t bf_elementbits;
950  uint32_t chunk_size;
951  char *bf_data;
952  uint32_t offset;
953 
954  /* We consider the ratio of the set sizes to determine
955  the number of bits per element, as the smaller set
956  should use more bits to maximize its set reduction
957  potential and minimize overall bandwidth consumption. */
958  bf_elementbits = 2 + ceil (log2 ((double)
960  / (double) op->my_element_count)));
961  if (bf_elementbits < 1)
962  bf_elementbits = 1; /* make sure k is not 0 */
963  /* optimize BF-size to ~50% of bits set */
964  bf_size = ceil ((double) (op->my_element_count
965  * bf_elementbits / log (2)));
967  "Sending Bloom filter (%u) of size %u bytes\n",
968  (unsigned int) bf_elementbits,
969  (unsigned int) bf_size);
971  bf_size,
972  bf_elementbits);
974  UINT32_MAX);
977  op);
978 
979  /* send our Bloom filter */
981  "# Intersection Bloom filters sent",
982  1,
983  GNUNET_NO);
984  chunk_size = 60 * 1024 - sizeof(struct BFMessage);
985  if (bf_size <= chunk_size)
986  {
987  /* singlepart */
988  chunk_size = bf_size;
989  ev = GNUNET_MQ_msg_extra (msg,
990  chunk_size,
994  op->local_bf,
995  (char *) &msg[1],
996  bf_size));
997  msg->sender_element_count = htonl (op->my_element_count);
998  msg->bloomfilter_total_length = htonl (bf_size);
999  msg->bits_per_element = htonl (bf_elementbits);
1000  msg->sender_mutator = htonl (op->salt);
1001  msg->element_xor_hash = op->my_xor;
1002  GNUNET_MQ_send (op->mq, ev);
1003  }
1004  else
1005  {
1006  /* multipart */
1007  bf_data = GNUNET_malloc (bf_size);
1010  op->local_bf,
1011  bf_data,
1012  bf_size));
1013  offset = 0;
1014  while (offset < bf_size)
1015  {
1016  if (bf_size - chunk_size < offset)
1017  chunk_size = bf_size - offset;
1018  ev = GNUNET_MQ_msg_extra (msg,
1019  chunk_size,
1021  GNUNET_memcpy (&msg[1],
1022  &bf_data[offset],
1023  chunk_size);
1024  offset += chunk_size;
1025  msg->sender_element_count = htonl (op->my_element_count);
1026  msg->bloomfilter_total_length = htonl (bf_size);
1027  msg->bits_per_element = htonl (bf_elementbits);
1028  msg->sender_mutator = htonl (op->salt);
1029  msg->element_xor_hash = op->my_xor;
1030  GNUNET_MQ_send (op->mq, ev);
1031  }
1032  GNUNET_free (bf_data);
1033  }
1035  op->local_bf = NULL;
1036 }
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
uint32_t sender_element_count
Number of elements the sender still has in the set.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint32_t bloomfilter_total_length
Total length of the bloomfilter data.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Randomness for IVs etc.
static int iterator_bf_create(void *cls, const struct GNUNET_HashCode *key, void *value)
Create initial bloomfilter based on all the elements given.
Bloom filter messages exchanged for set intersection calculation.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
int GNUNET_CONTAINER_bloomfilter_get_raw_data(const struct GNUNET_CONTAINER_BloomFilter *bf, char *data, size_t size)
Copy the raw data of this Bloom filter into the given data array.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
uint32_t bits_per_element
Number of bits (k-value) used in encoding the bloomfilter.
uint32_t salt
Salt to use for the operation.
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
uint32_t remote_element_count
Remote peers element count.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_BF
Bloom filter message for intersection exchange started by Bob.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
uint32_t sender_mutator
Mutator used with this bloomfilter.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ finished_local_operations()

static void finished_local_operations ( void *  cls)
static

Remember that we are done dealing with the local client AND have sent the other peer our message that we are done, so we are not just waiting for the channel to die before telling the local client that we are done as our last act.

Parameters
clsthe struct Operation.

Definition at line 1048 of file gnunet-service-seti.c.

References Operation::channel_death_expected, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, Operation::phase, and PHASE_FINISHED.

Referenced by send_p2p_done().

1049 {
1050  struct Operation *op = cls;
1051 
1053  "DONE sent to other peer, now waiting for other end to close the channel\n");
1054  op->phase = PHASE_FINISHED;
1056 }
enum IntersectionOperationPhase phase
Current state of the operation.
The protocol is over.
Operation context used to execute a set operation.
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int channel_death_expected
Set whenever we reach the state where the death of the channel is perfectly find and should NOT resul...
Here is the caller graph for this function:

◆ send_p2p_done()

static void send_p2p_done ( struct Operation op)
static

Notify the other peer that we are done.

Once this message is out, we still need to notify the local client that we are done.

Parameters
opoperation to notify for.

Definition at line 1067 of file gnunet-service-seti.c.

References Operation::channel_death_expected, IntersectionDoneMessage::element_xor_hash, IntersectionDoneMessage::final_element_count, finished_local_operations(), GNUNET_assert, GNUNET_MESSAGE_TYPE_SETI_P2P_DONE, GNUNET_MQ_msg, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_NO, Operation::mq, Operation::my_element_count, Operation::my_xor, Operation::phase, and PHASE_MUST_SEND_DONE.

Referenced by process_bf(), and send_remaining_elements().

1068 {
1069  struct GNUNET_MQ_Envelope *ev;
1070  struct IntersectionDoneMessage *idm;
1071 
1074  ev = GNUNET_MQ_msg (idm,
1076  idm->final_element_count = htonl (op->my_element_count);
1077  idm->element_xor_hash = op->my_xor;
1080  op);
1081  GNUNET_MQ_send (op->mq,
1082  ev);
1083 }
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
uint32_t final_element_count
Final number of elements in intersection.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:787
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
We must next send the P2P DONE message (after finishing mostly with the local client).
static void finished_local_operations(void *cls)
Remember that we are done dealing with the local client AND have sent the other peer our message that...
uint32_t my_element_count
Current element count contained within my_elements.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_DONE
Intersection operation is done.
Last message, send to confirm the final set.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
int channel_death_expected
Set whenever we reach the state where the death of the channel is perfectly find and should NOT resul...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_remaining_elements()

static void send_remaining_elements ( void *  cls)
static

Send all elements in the full result iterator.

Parameters
clsthe struct Operation *

Definition at line 1092 of file gnunet-service-seti.c.

References Operation::client_request_id, Set::cs, GNUNET_SETI_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SETI_Element::element_type, GNUNET_SETI_ResultMessage::element_type, Operation::full_result_iter, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_CONTAINER_multihashmap_iterator_next(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETI_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_SETI_STATUS_ADD_LOCAL, ClientState::mq, Operation::phase, PHASE_DONE_RECEIVED, PHASE_FINISHED, PHASE_MUST_SEND_DONE, GNUNET_SETI_ResultMessage::request_id, res, GNUNET_SETI_ResultMessage::result_status, Operation::return_intersection, send_client_done_and_destroy(), send_p2p_done(), Operation::set, and GNUNET_SETI_Element::size.

Referenced by handle_intersection_p2p_done(), and process_bf().

1093 {
1094  struct Operation *op = cls;
1095  const void *nxt;
1096  const struct ElementEntry *ee;
1097  struct GNUNET_MQ_Envelope *ev;
1098  struct GNUNET_SETI_ResultMessage *rm;
1099  const struct GNUNET_SETI_Element *element;
1100  int res;
1101 
1102  if (GNUNET_NO == op->return_intersection)
1103  {
1104  GNUNET_break (0);
1105  return; /* Wrong mode for transmitting removed elements */
1106  }
1108  op->full_result_iter,
1109  NULL,
1110  &nxt);
1111  if (GNUNET_NO == res)
1112  {
1114  "Sending done and destroy because iterator ran out\n");
1116  op->full_result_iter);
1117  op->full_result_iter = NULL;
1118  if (PHASE_DONE_RECEIVED == op->phase)
1119  {
1120  op->phase = PHASE_FINISHED;
1122  }
1123  else if (PHASE_MUST_SEND_DONE == op->phase)
1124  {
1125  send_p2p_done (op);
1126  }
1127  else
1128  {
1129  GNUNET_assert (0);
1130  }
1131  return;
1132  }
1133  ee = nxt;
1134  element = &ee->element;
1136  "Sending element %s:%u to client (full set)\n",
1137  GNUNET_h2s (&ee->element_hash),
1138  element->size);
1139  GNUNET_assert (0 != op->client_request_id);
1140  ev = GNUNET_MQ_msg_extra (rm,
1141  element->size,
1143  GNUNET_assert (NULL != ev);
1145  rm->request_id = htonl (op->client_request_id);
1146  rm->element_type = element->element_type;
1147  GNUNET_memcpy (&rm[1],
1148  element->data,
1149  element->size);
1152  op);
1153  GNUNET_MQ_send (op->set->cs->mq,
1154  ev);
1155 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: seti.h:191
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
uint16_t size
Number of bytes in the buffer pointed to by data.
int return_intersection
When are elements sent to the client, and which elements are sent?
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Element should be added to the result set of the local peer, i.e.
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:787
Information about an element element in the set.
uint32_t request_id
id the result belongs to
Definition: seti.h:206
Element stored in a set.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
const void * data
Actual data of the element.
The protocol is over.
#define GNUNET_MESSAGE_TYPE_SETI_RESULT
Handle result message from operation.
static int res
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
We must next send the P2P DONE message (after finishing mostly with the local client).
struct ClientState * cs
Client that owns the set.
Operation context used to execute a set operation.
static void send_p2p_done(struct Operation *op)
Notify the other peer that we are done.
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETI_Status in NBO.
Definition: seti.h:212
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
We have received the P2P DONE message, and must finish with the local client before terminating the c...
uint16_t element_type
Application-specific element type.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: seti.h:217
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_map_unfiltered()

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

Fills the "my_elements" hashmap with the initial set of (non-deleted) elements from the set of the specification.

Parameters
clsclosure with the struct Operation *
keycurrent key code for the element
valuevalue in the hash map with the struct ElementEntry *
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 1168 of file gnunet-service-seti.c.

References _GSS_is_element_of_operation(), ElementEntry::element, ElementEntry::element_hash, GNUNET_break, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, Operation::my_elements, Operation::my_xor, GNUNET_SET_Element::size, and value.

Referenced by begin_bf_exchange().

1171 {
1172  struct ElementEntry *ee = value;
1173  struct Operation *op = cls;
1174 
1175  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
1176  return GNUNET_YES; /* element not live in operation's generation */
1178  &ee->element_hash,
1179  &op->my_xor);
1181  "Initial full initialization of my_elements, adding %s:%u\n",
1182  GNUNET_h2s (&ee->element_hash),
1183  ee->element.size);
1186  &ee->element_hash,
1187  ee,
1189  return GNUNET_YES;
1190 }
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_HashCode element_hash
Hash of the element.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
Operation context used to execute a set operation.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:202
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_element_count()

static void send_element_count ( struct Operation op)
static

Send our element count to the peer, in case our element count is lower than theirs.

Parameters
opintersection operation

Definition at line 1200 of file gnunet-service-seti.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO, GNUNET_MQ_msg, GNUNET_MQ_send(), Operation::mq, msg, Operation::my_element_count, and IntersectionElementInfoMessage::sender_element_count.

Referenced by handle_client_accept().

1201 {
1202  struct GNUNET_MQ_Envelope *ev;
1204 
1206  "Sending our element count (%u)\n",
1207  op->my_element_count);
1208  ev = GNUNET_MQ_msg (msg,
1210  msg->sender_element_count = htonl (op->my_element_count);
1211  GNUNET_MQ_send (op->mq, ev);
1212 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t sender_element_count
mutator used with this bloomfilter.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO
Information about the element count for intersection.
uint32_t my_element_count
Current element count contained within my_elements.
During intersection, the first (and possibly second) message send it the number of elements in the se...
#define GNUNET_log(kind,...)
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ begin_bf_exchange()

static void begin_bf_exchange ( struct Operation op)
static

We go first, initialize our map with all elements and send the first Bloom filter.

Parameters
opoperation to start exchange for

Definition at line 1222 of file gnunet-service-seti.c.

References Set::content, SetContent::elements, GNUNET_CONTAINER_multihashmap_iterate(), initialize_map_unfiltered(), Operation::phase, PHASE_BF_EXCHANGE, send_bloomfilter(), and Operation::set.

Referenced by handle_client_accept(), and handle_intersection_p2p_element_info().

1223 {
1224  op->phase = PHASE_BF_EXCHANGE;
1227  op);
1228  send_bloomfilter (op);
1229 }
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
static void send_bloomfilter(struct Operation *op)
Send a bloomfilter to our peer.
static int initialize_map_unfiltered(void *cls, const struct GNUNET_HashCode *key, void *value)
Fills the "my_elements" hashmap with the initial set of (non-deleted) elements from the set of the sp...
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_intersection_p2p_element_info()

static void handle_intersection_p2p_element_info ( void *  cls,
const struct IntersectionElementInfoMessage msg 
)
static

Handle the initial struct IntersectionElementInfoMessage from a remote peer.

Parameters
clsthe intersection operation
mhthe header of the message

Definition at line 1240 of file gnunet-service-seti.c.

References begin_bf_exchange(), Operation::channel, fail_intersection_operation(), GNUNET_break, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, Operation::my_element_count, Operation::phase, PHASE_COUNT_SENT, PHASE_INITIAL, Operation::remote_bf, Operation::remote_element_count, and IntersectionElementInfoMessage::sender_element_count.

1243 {
1244  struct Operation *op = cls;
1245 
1246  op->remote_element_count = ntohl (msg->sender_element_count);
1248  "Received remote element count (%u), I have %u\n",
1250  op->my_element_count);
1251  if (((PHASE_INITIAL != op->phase) &&
1252  (PHASE_COUNT_SENT != op->phase)) ||
1253  (op->my_element_count > op->remote_element_count) ||
1254  (0 == op->my_element_count) ||
1255  (0 == op->remote_element_count))
1256  {
1257  GNUNET_break_op (0);
1259  return;
1260  }
1261  GNUNET_break (NULL == op->remote_bf);
1262  begin_bf_exchange (op);
1264 }
enum IntersectionOperationPhase phase
Current state of the operation.
We are just starting.
static void begin_bf_exchange(struct Operation *op)
We go first, initialize our map with all elements and send the first Bloom filter.
We have send the number of our elements to the other peer, but did not setup our element set yet...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t sender_element_count
mutator used with this bloomfilter.
Operation context used to execute a set operation.
uint32_t my_element_count
Current element count contained within my_elements.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#define GNUNET_log(kind,...)
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
uint32_t remote_element_count
Remote peers element count.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ process_bf()

static void process_bf ( struct Operation op)
static

Process a Bloomfilter once we got all the chunks.

Parameters
opthe intersection operation

Definition at line 1273 of file gnunet-service-seti.c.

References Set::content, SetContent::elements, fail_intersection_operation(), filtered_map_initialization(), Operation::full_result_iter, GNUNET_break_op, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_iterator_create(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcmp, GNUNET_YES, iterator_bf_reduce(), Operation::local_bf, Operation::my_element_count, Operation::my_elements, Operation::my_xor, Operation::other_xor, Operation::phase, PHASE_BF_EXCHANGE, PHASE_COUNT_SENT, PHASE_DONE_RECEIVED, PHASE_FINISHED, PHASE_INITIAL, PHASE_MUST_SEND_DONE, Operation::remote_bf, Operation::remote_element_count, Operation::return_intersection, send_bloomfilter(), send_p2p_done(), send_remaining_elements(), and Operation::set.

Referenced by handle_intersection_p2p_bf().

1274 {
1276  "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n",
1277  op->phase,
1279  op->my_element_count,
1281  switch (op->phase)
1282  {
1283  case PHASE_INITIAL:
1284  GNUNET_break_op (0);
1286  return;
1287  case PHASE_COUNT_SENT:
1288  /* This is the first BF being sent, build our initial map with
1289  filtering in place */
1290  op->my_element_count = 0;
1293  op);
1294  break;
1295  case PHASE_BF_EXCHANGE:
1296  /* Update our set by reduction */
1299  op);
1300  break;
1301  case PHASE_MUST_SEND_DONE:
1302  GNUNET_break_op (0);
1304  return;
1305  case PHASE_DONE_RECEIVED:
1306  GNUNET_break_op (0);
1308  return;
1309  case PHASE_FINISHED:
1310  GNUNET_break_op (0);
1312  return;
1313  }
1315  op->remote_bf = NULL;
1316 
1317  if ((0 == op->my_element_count) || /* fully disjoint */
1318  ((op->my_element_count == op->remote_element_count) &&
1319  (0 == GNUNET_memcmp (&op->my_xor,
1320  &op->other_xor))))
1321  {
1322  /* we are done */
1325  "Intersection succeeded, sending DONE to other peer\n");
1327  op->local_bf = NULL;
1328  if (GNUNET_YES == op->return_intersection)
1329  {
1331  "Sending full result set (%u elements)\n",
1333  op->full_result_iter
1335  op->my_elements);
1337  return;
1338  }
1339  send_p2p_done (op);
1340  return;
1341  }
1342  op->phase = PHASE_BF_EXCHANGE;
1343  send_bloomfilter (op);
1344 }
struct GNUNET_CONTAINER_BloomFilter * local_bf
BF of the set&#39;s element.
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
int return_intersection
When are elements sent to the client, and which elements are sent?
static int iterator_bf_reduce(void *cls, const struct GNUNET_HashCode *key, void *value)
Removes elements from our hashmap if they are not contained within the provided remote bloomfilter...
We are just starting.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
We have send the number of our elements to the other peer, but did not setup our element set yet...
static int filtered_map_initialization(void *cls, const struct GNUNET_HashCode *key, void *value)
Fills the "my_elements" hashmap with all relevant elements.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
The protocol is over.
static void send_bloomfilter(struct Operation *op)
Send a bloomfilter to our peer.
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
We must next send the P2P DONE message (after finishing mostly with the local client).
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
static void send_p2p_done(struct Operation *op)
Notify the other peer that we are done.
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
#define GNUNET_log(kind,...)
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
uint32_t remote_element_count
Remote peers element count.
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
We have received the P2P DONE message, and must finish with the local client before terminating the c...
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
struct GNUNET_HashCode other_xor
XOR of the keys of all of the elements (remaining) in the other peer&#39;s set.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_intersection_p2p_bf()

static int check_intersection_p2p_bf ( void *  cls,
const struct BFMessage msg 
)
static

Check an BF message from a remote peer.

Parameters
clsthe intersection operation
msgthe header of the message
Returns
GNUNET_OK if msg is well-formed

Definition at line 1355 of file gnunet-service-seti.c.

References GNUNET_OK.

1357 {
1358  struct Operation *op = cls;
1359 
1360  (void) op;
1361  return GNUNET_OK;
1362 }
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_intersection_p2p_bf()

static void handle_intersection_p2p_bf ( void *  cls,
const struct BFMessage msg 
)
static

Handle an BF message from a remote peer.

Parameters
clsthe intersection operation
msgthe header of the message

Definition at line 1372 of file gnunet-service-seti.c.

References Operation::bf_bits_per_element, Operation::bf_data, Operation::bf_data_offset, Operation::bf_data_size, BFMessage::bits_per_element, BFMessage::bloomfilter_total_length, Operation::channel, BFMessage::element_xor_hash, fail_intersection_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_free, GNUNET_malloc, GNUNET_memcpy, BFMessage::header, Operation::other_xor, Operation::phase, PHASE_BF_EXCHANGE, PHASE_COUNT_SENT, PHASE_INITIAL, process_bf(), Operation::remote_bf, Operation::remote_element_count, Operation::salt, BFMessage::sender_element_count, BFMessage::sender_mutator, and GNUNET_MessageHeader::size.

1374 {
1375  struct Operation *op = cls;
1376  uint32_t bf_size;
1377  uint32_t chunk_size;
1378  uint32_t bf_bits_per_element;
1379 
1380  switch (op->phase)
1381  {
1382  case PHASE_INITIAL:
1383  GNUNET_break_op (0);
1385  return;
1386 
1387  case PHASE_COUNT_SENT:
1388  case PHASE_BF_EXCHANGE:
1389  bf_size = ntohl (msg->bloomfilter_total_length);
1390  bf_bits_per_element = ntohl (msg->bits_per_element);
1391  chunk_size = htons (msg->header.size) - sizeof(struct BFMessage);
1392  op->other_xor = msg->element_xor_hash;
1393  if (bf_size == chunk_size)
1394  {
1395  if (NULL != op->bf_data)
1396  {
1397  GNUNET_break_op (0);
1399  return;
1400  }
1401  /* single part, done here immediately */
1402  op->remote_bf
1403  = GNUNET_CONTAINER_bloomfilter_init ((const char *) &msg[1],
1404  bf_size,
1405  bf_bits_per_element);
1406  op->salt = ntohl (msg->sender_mutator);
1407  op->remote_element_count = ntohl (msg->sender_element_count);
1408  process_bf (op);
1409  break;
1410  }
1411  /* multipart chunk */
1412  if (NULL == op->bf_data)
1413  {
1414  /* first chunk, initialize */
1415  op->bf_data = GNUNET_malloc (bf_size);
1416  op->bf_data_size = bf_size;
1417  op->bf_bits_per_element = bf_bits_per_element;
1418  op->bf_data_offset = 0;
1419  op->salt = ntohl (msg->sender_mutator);
1420  op->remote_element_count = ntohl (msg->sender_element_count);
1421  }
1422  else
1423  {
1424  /* increment */
1425  if ((op->bf_data_size != bf_size) ||
1426  (op->bf_bits_per_element != bf_bits_per_element) ||
1427  (op->bf_data_offset + chunk_size > bf_size) ||
1428  (op->salt != ntohl (msg->sender_mutator)) ||
1429  (op->remote_element_count != ntohl (msg->sender_element_count)))
1430  {
1431  GNUNET_break_op (0);
1433  return;
1434  }
1435  }
1437  (const char *) &msg[1],
1438  chunk_size);
1439  op->bf_data_offset += chunk_size;
1440  if (op->bf_data_offset == bf_size)
1441  {
1442  /* last chunk, run! */
1443  op->remote_bf
1445  bf_size,
1446  bf_bits_per_element);
1447  GNUNET_free (op->bf_data);
1448  op->bf_data = NULL;
1449  op->bf_data_size = 0;
1450  process_bf (op);
1451  }
1452  break;
1453 
1454  default:
1455  GNUNET_break_op (0);
1457  return;
1458  }
1460 }
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
enum IntersectionOperationPhase phase
Current state of the operation.
uint32_t bf_bits_per_element
size of the bloomfilter
uint32_t bf_data_size
size of the bloomfilter in bf_data.
uint32_t sender_element_count
Number of elements the sender still has in the set.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
We are just starting.
uint32_t bf_data_offset
How many bytes of bf_data are valid?
We have send the number of our elements to the other peer, but did not setup our element set yet...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t bloomfilter_total_length
Total length of the bloomfilter data.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Bloom filter messages exchanged for set intersection calculation.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
Operation context used to execute a set operation.
uint32_t bits_per_element
Number of bits (k-value) used in encoding the bloomfilter.
struct GNUNET_CONTAINER_BloomFilter * remote_bf
The bf we currently receive.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint32_t salt
Salt to use for the operation.
static void process_bf(struct Operation *op)
Process a Bloomfilter once we got all the chunks.
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
uint32_t remote_element_count
Remote peers element count.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
uint32_t sender_mutator
Mutator used with this bloomfilter.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_HashCode other_xor
XOR of the keys of all of the elements (remaining) in the other peer&#39;s set.
char * bf_data
For multipart BF transmissions, we have to store the bloomfilter-data until we fully received it...
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:

◆ filter_all()

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

Remove all elements from our hashmap.

Parameters
clsclosure with the struct Operation *
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 1472 of file gnunet-service-seti.c.

References ElementEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash_xor(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_YES, Operation::my_element_count, Operation::my_elements, Operation::my_xor, send_client_removed_element(), GNUNET_SET_Element::size, and value.

Referenced by handle_intersection_p2p_done().

1475 {
1476  struct Operation *op = cls;
1477  struct ElementEntry *ee = value;
1478 
1479  GNUNET_break (0 < op->my_element_count);
1480  op->my_element_count--;
1482  &ee->element_hash,
1483  &op->my_xor);
1485  "Final reduction of my_elements, removing %s:%u\n",
1486  GNUNET_h2s (&ee->element_hash),
1487  ee->element.size);
1490  &ee->element_hash,
1491  ee));
1493  &ee->element);
1494  return GNUNET_YES;
1495 }
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * value
Value of the record to add/remove.
Information about an element element in the set.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
static void send_client_removed_element(struct Operation *op, struct GNUNET_SETI_Element *element)
If applicable in the current operation mode, send a result message to the client indicating we remove...
Operation context used to execute a set operation.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:202
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_intersection_p2p_done()

static void handle_intersection_p2p_done ( void *  cls,
const struct IntersectionDoneMessage idm 
)
static

Handle a done message from a remote peer.

Parameters
clsthe intersection operation
mhthe message

Definition at line 1505 of file gnunet-service-seti.c.

References Operation::channel, Operation::client_done_sent, IntersectionDoneMessage::element_xor_hash, fail_intersection_operation(), filter_all(), IntersectionDoneMessage::final_element_count, Operation::full_result_iter, GNUNET_assert, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_iterator_create(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcmp, GNUNET_NO, GNUNET_YES, Operation::my_element_count, Operation::my_elements, Operation::my_xor, Operation::phase, PHASE_BF_EXCHANGE, PHASE_DONE_RECEIVED, PHASE_FINISHED, Operation::return_intersection, send_client_done_and_destroy(), and send_remaining_elements().

1507 {
1508  struct Operation *op = cls;
1509 
1510  if (PHASE_BF_EXCHANGE != op->phase)
1511  {
1512  /* wrong phase to conclude? FIXME: Or should we allow this
1513  if the other peer has _initially_ already an empty set? */
1514  GNUNET_break_op (0);
1516  return;
1517  }
1518  if (0 == ntohl (idm->final_element_count))
1519  {
1520  /* other peer determined empty set is the intersection,
1521  remove all elements */
1523  &filter_all,
1524  op);
1525  }
1526  if ((op->my_element_count != ntohl (idm->final_element_count)) ||
1527  (0 != GNUNET_memcmp (&op->my_xor,
1528  &idm->element_xor_hash)))
1529  {
1530  /* Other peer thinks we are done, but we disagree on the result! */
1531  GNUNET_break_op (0);
1533  return;
1534  }
1536  "Got IntersectionDoneMessage, have %u elements in intersection\n",
1537  op->my_element_count);
1538  op->phase = PHASE_DONE_RECEIVED;
1540 
1542  if (GNUNET_YES == op->return_intersection)
1543  {
1545  "Sending full result set to client (%u elements)\n",
1547  op->full_result_iter
1550  return;
1551  }
1552  op->phase = PHASE_FINISHED;
1554 }
struct GNUNET_HashCode my_xor
XOR of the keys of all of the elements (remaining) in my set.
uint32_t final_element_count
Final number of elements in intersection.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
int return_intersection
When are elements sent to the client, and which elements are sent?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
The protocol is over.
struct GNUNET_HashCode element_xor_hash
XOR of all hashes over all elements remaining in the set.
static void send_remaining_elements(void *cls)
Send all elements in the full result iterator.
int client_done_sent
Did we send the client that we are done?
Operation context used to execute a set operation.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
static int filter_all(void *cls, const struct GNUNET_HashCode *key, void *value)
Remove all elements from our hashmap.
uint32_t my_element_count
Current element count contained within my_elements.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
static void send_client_done_and_destroy(void *cls)
Signal to the client that the operation has finished and destroy the operation.
#define GNUNET_log(kind,...)
static void fail_intersection_operation(struct Operation *op)
Inform the client that the intersection operation has failed, and proceed to destroy the evaluate ope...
struct GNUNET_CONTAINER_MultiHashMapIterator * full_result_iter
Iterator for sending the final set of my_elements to the client.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
We have initialized our set and are now reducing it by exchanging Bloom filters until one party notic...
We have received the P2P DONE message, and must finish with the local client before terminating the c...
Here is the call graph for this function:

◆ get_incoming()

static struct Operation* get_incoming ( uint32_t  id)
static

Get the incoming socket associated with the given id.

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

Definition at line 1566 of file gnunet-service-seti.c.

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

Referenced by handle_client_accept(), and handle_client_reject().

1567 {
1568  for (struct Listener *listener = listener_head; NULL != listener;
1569  listener = listener->next)
1570  {
1571  for (struct Operation *op = listener->op_head; NULL != op; op = op->next)
1572  if (op->suggest_id == id)
1573  return op;
1574  }
1575  return NULL;
1576 }
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
struct Listener * next
Listeners are held in a doubly linked list.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
static struct Listener * listener_head
Listeners are held in a doubly linked list.
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.
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 1588 of file gnunet-service-seti.c.

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

Referenced by run().

1591 {
1592  struct ClientState *cs;
1593 
1594  num_clients++;
1595  cs = GNUNET_new (struct ClientState);
1596  cs->client = c;
1597  cs->mq = mq;
1598  return cs;
1599 }
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
static unsigned int num_clients
Number of active clients.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SERVICE_Client * client
Client this is about.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Here is the caller graph for this function:

◆ destroy_elements_iterator()

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

Iterator over hash map entries to free element entries.

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

Definition at line 1611 of file gnunet-service-seti.c.

References GNUNET_free, GNUNET_YES, and value.

Referenced by client_disconnect_cb().

1614 {
1615  struct ElementEntry *ee = value;
1616 
1617  GNUNET_free (ee);
1618  return GNUNET_YES;
1619 }
static char * value
Value of the record to add/remove.
Information about an element element in the set.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ client_disconnect_cb()

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

Clean up after a client has disconnected.

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

Definition at line 1630 of file gnunet-service-seti.c.

References _GSS_operation_destroy(), Operation::client_request_id, destroy_elements_iterator(), SetContent::elements, GNUNET_assert, GNUNET_CADET_close_port(), GNUNET_CADET_disconnect(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_YES, in_shutdown, incoming_destroy(), ClientState::listener, num_clients, op, Listener::op_head, Listener::open_port, Operation::peer, SetContent::refcount, and ClientState::set.

Referenced by run().

1633 {
1634  struct ClientState *cs = internal_cls;
1635  struct Operation *op;
1636  struct Listener *listener;
1637  struct Set *set;
1638 
1639  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, cleaning up\n");
1640  if (NULL != (set = cs->set))
1641  {
1642  struct SetContent *content = set->content;
1643 
1644  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's set\n");
1645  /* Destroy pending set operations */
1646  while (NULL != set->ops_head)
1647  _GSS_operation_destroy (set->ops_head);
1648 
1649  /* free set content (or at least decrement RC) */
1650  set->content = NULL;
1651  GNUNET_assert (0 != content->refcount);
1652  content->refcount--;
1653  if (0 == content->refcount)
1654  {
1655  GNUNET_assert (NULL != content->elements);
1658  NULL);
1660  content->elements = NULL;
1661  GNUNET_free (content);
1662  }
1663  GNUNET_free (set);
1664  }
1665 
1666  if (NULL != (listener = cs->listener))
1667  {
1668  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying client's listener\n");
1669  GNUNET_CADET_close_port (listener->open_port);
1670  listener->open_port = NULL;
1671  while (NULL != (op = listener->op_head))
1672  {
1674  "Destroying incoming operation `%u' from peer `%s'\n",
1675  (unsigned int) op->client_request_id,
1676  GNUNET_i2s (&op->peer));
1677  incoming_destroy (op);
1678  }
1680  GNUNET_free (listener);
1681  }
1682  GNUNET_free (cs);
1683  num_clients--;
1684  if ((GNUNET_YES == in_shutdown) && (0 == num_clients))
1685  {
1686  if (NULL != cadet)
1687  {
1689  cadet = NULL;
1690  }
1691  }
1692 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
static unsigned int num_clients
Number of active clients.
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
unsigned int refcount
Number of references to the content.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
A set that supports a specific operation with other peers.
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET...
static struct Listener * listener_head
Listeners are held in a doubly linked list.
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
Operation context used to execute a set operation.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:808
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_incoming_msg()

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

Check a request for a set operation from another peer.

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

Definition at line 1704 of file gnunet-service-seti.c.

References GNUNET_break, GNUNET_break_op, GNUNET_MQ_extract_nested_mh, GNUNET_OK, GNUNET_SETI_CONTEXT_MESSAGE_MAX_SIZE, GNUNET_SYSERR, Operation::listener, GNUNET_MessageHeader::size, and Operation::suggest_id.

1706 {
1707  struct Operation *op = cls;
1708  struct Listener *listener = op->listener;
1709  const struct GNUNET_MessageHeader *nested_context;
1710 
1711  /* double operation request */
1712  if (0 != op->suggest_id)
1713  {
1714  GNUNET_break_op (0);
1715  return GNUNET_SYSERR;
1716  }
1717  /* This should be equivalent to the previous condition, but can't hurt to check twice */
1718  if (NULL == listener)
1719  {
1720  GNUNET_break (0);
1721  return GNUNET_SYSERR;
1722  }
1723  nested_context = GNUNET_MQ_extract_nested_mh (msg);
1724  if ((NULL != nested_context) &&
1725  (ntohs (nested_context->size) > GNUNET_SETI_CONTEXT_MESSAGE_MAX_SIZE))
1726  {
1727  GNUNET_break_op (0);
1728  return GNUNET_SYSERR;
1729  }
1730  return GNUNET_OK;
1731 }
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Operation context used to execute a set operation.
#define GNUNET_SETI_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.

◆ 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 1752 of file gnunet-service-seti.c.

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

1754 {
1755  struct Operation *op = cls;
1756  struct Listener *listener = op->listener;
1757  const struct GNUNET_MessageHeader *nested_context;
1758  struct GNUNET_MQ_Envelope *env;
1759  struct GNUNET_SETI_RequestMessage *cmsg;
1760 
1761  nested_context = GNUNET_MQ_extract_nested_mh (msg);
1762  /* Make a copy of the nested_context (application-specific context
1763  information that is opaque to set) so we can pass it to the
1764  listener later on */
1765  if (NULL != nested_context)
1766  op->context_msg = GNUNET_copy_message (nested_context);
1767  op->remote_element_count = ntohl (msg->element_count);
1768  GNUNET_log (
1770  "Received P2P operation request (port %s) for active listener\n",
1771  GNUNET_h2s (&op->listener->app_id));
1772  GNUNET_assert (0 == op->suggest_id);
1773  if (0 == suggest_id)
1774  suggest_id++;
1775  op->suggest_id = suggest_id++;
1776  GNUNET_assert (NULL != op->timeout_task);
1778  op->timeout_task = NULL;
1779  env = GNUNET_MQ_msg_nested_mh (cmsg,
1781  op->context_msg);
1782  GNUNET_log (
1784  "Suggesting incoming request with accept id %u to listener %p of client %p\n",
1785  op->suggest_id,
1786  listener,
1787  listener->cs);
1788  cmsg->accept_id = htonl (op->suggest_id);
1789  cmsg->peer_id = op->peer;
1790  GNUNET_MQ_send (listener->cs->mq, env);
1791  /* NOTE: GNUNET_CADET_receive_done() will be called in
1792  #handle_client_accept() */
1793 }
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: seti.h:134
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
uint32_t suggest_id
Unique request id for the request from a remote peer, sent to the client, which will accept or reject...
uint32_t element_count
For Intersection: my element count.
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
#define GNUNET_MESSAGE_TYPE_SETI_REQUEST
Notify the client of an incoming request from a remote peer.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
static uint32_t suggest_id
Counter for allocating unique IDs for clients, used to identify incoming operation requests from remo...
struct GNUNET_PeerIdentity peer_id
Identity of the requesting peer.
Definition: seti.h:139
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Operation context used to execute a set operation.
#define GNUNET_log(kind,...)
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
A request for an operation with another client.
Definition: seti.h:123
struct ClientState * cs
Client that owns the listener.
uint32_t remote_element_count
Remote peers element count.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
Here is the call graph for this function:

◆ handle_client_create_set()

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

Called when a client wants to create a new set.

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

Parameters
clsclient that sent the message
mmessage sent by the client

Definition at line 1805 of file gnunet-service-seti.c.

References ClientState::client, Set::cs, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_YES, and ClientState::set.

1807 {
1808  struct ClientState *cs = cls;
1809  struct Set *set;
1810 
1812  "Client created new intersection set\n");
1813  if (NULL != cs->set)
1814  {
1815  /* There can only be one set per client */
1816  GNUNET_break (0);
1818  return;
1819  }
1820  set = GNUNET_new (struct Set);
1821  set->content = GNUNET_new (struct SetContent);
1822  set->content->refcount = 1;
1823  set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
1824  GNUNET_YES);
1825  set->cs = cs;
1826  cs->set = set;
1828 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A set that supports a specific operation with other peers.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
struct ClientState * cs
Client that owns the set.
SetContent stores the actual set elements, which may be shared by multiple generations derived from o...
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
Here is the call graph for this function:

◆ incoming_timeout_cb()

static void incoming_timeout_cb ( void *  cls)
static

Timeout happens iff:

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

Definition at line 1841 of file gnunet-service-seti.c.

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

Referenced by channel_new_cb().

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

◆ channel_new_cb()

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

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

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

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

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

Definition at line 1869 of file gnunet-service-seti.c.

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

Referenced by handle_client_listen().

1872 {
1873  struct Listener *listener = cls;
1874  struct Operation *op;
1875 
1877  "New incoming channel\n");
1878  op = GNUNET_new (struct Operation);
1879  op->listener = listener;
1880  op->peer = *source;
1881  op->channel = channel;
1882  op->mq = GNUNET_CADET_get_mq (op->channel);
1884  UINT32_MAX);
1887  op);
1889  listener->op_tail,
1890  op);
1891  return op;
1892 }
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define INCOMING_CHANNEL_TIMEOUT
How long do we hold on to an incoming channel if there is no local listener before giving up...
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task, if the incoming peer has not been accepted after the timeout, it will be disconnected...
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
Randomness for IVs etc.
static void incoming_timeout_cb(void *cls)
Timeout happens iff:
static GstElement * source
Appsrc instance into which we write data for the pipeline.
Operation context used to execute a set operation.
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint32_t salt
Salt to use for the operation.
#define GNUNET_log(kind,...)
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1082
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 1912 of file gnunet-service-seti.c.

References _GSS_operation_destroy2(), and Operation::channel.

Referenced by handle_client_evaluate(), and handle_client_listen().

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

◆ channel_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 1937 of file gnunet-service-seti.c.

Referenced by handle_client_evaluate(), and handle_client_listen().

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

◆ handle_client_listen()

static void handle_client_listen ( void *  cls,
const struct GNUNET_SETI_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 1952 of file gnunet-service-seti.c.

References GNUNET_SETI_ListenMessage::app_id, Listener::app_id, channel_end_cb(), channel_new_cb(), channel_window_cb(), ClientState::client, Listener::cs, GNUNET_break, GNUNET_CADET_open_port(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_P2P_BF, GNUNET_MESSAGE_TYPE_SETI_P2P_DONE, GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO, GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST, 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, and Listener::open_port.

1954 {
1955  struct ClientState *cs = cls;
1956  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1957  GNUNET_MQ_hd_var_size (incoming_msg,
1959  struct OperationRequestMessage,
1960  NULL),
1961  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
1964  NULL),
1965  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
1967  struct BFMessage,
1968  NULL),
1969  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
1971  struct IntersectionDoneMessage,
1972  NULL),
1974  };
1975  struct Listener *listener;
1976 
1977  if (NULL != cs->listener)
1978  {
1979  /* max. one active listener per client! */
1980  GNUNET_break (0);
1982  return;
1983  }
1984  listener = GNUNET_new (struct Listener);
1985  listener->cs = cs;
1986  cs->listener = listener;
1987  listener->app_id = msg->app_id;
1989  listener_tail,
1990  listener);
1992  "New listener for set intersection created (port %s)\n",
1993  GNUNET_h2s (&listener->app_id));
1994  listener->open_port = GNUNET_CADET_open_port (cadet,
1995  &msg->app_id,
1996  &channel_new_cb,
1997  listener,
1999  &channel_end_cb,
2000  cadet_handlers);
2002 }
State we keep per client.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
static void channel_window_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_HashCode app_id
application id
Definition: seti.h:68
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incomming MQ-based channels.
Definition: cadet_api.c:970
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void * channel_new_cb(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
Method called whenever another peer has added us to a channel the other peer initiated.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO
Information about the element count for intersection.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST
Request to begin set intersection operation.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
Message handler for a specific message type.
Bloom filter messages exchanged for set intersection calculation.
static struct Listener * listener_head
Listeners are held in a doubly linked list.
struct GNUNET_CADET_Port * open_port
The port we are listening on with CADET.
static void channel_end_cb(void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
During intersection, the first (and possibly second) message send it the number of elements in the se...
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_DONE
Intersection operation is done.
#define GNUNET_log(kind,...)
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
Last message, send to confirm the final set.
struct ClientState * cs
Client that owns the listener.
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_BF
Bloom filter message for intersection exchange started by Bob.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
Here is the call graph for this function:

◆ handle_client_reject()

static void handle_client_reject ( void *  cls,
const struct GNUNET_SETI_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 2013 of file gnunet-service-seti.c.

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

2015 {
2016  struct ClientState *cs = cls;
2017  struct Operation *op;
2018 
2019  op = get_incoming (ntohl (msg->accept_reject_id));
2020  if (NULL == op)
2021  {
2022  /* no matching incoming operation for this reject;
2023  could be that the other peer already disconnected... */
2025  "Client rejected unknown operation %u\n",
2026  (unsigned int) ntohl (msg->accept_reject_id));
2028  return;
2029  }
2031  "Peer request (app %s) rejected by client\n",
2032  GNUNET_h2s (&cs->listener->app_id));
2035 }
State we keep per client.
static void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static struct Operation * get_incoming(uint32_t id)
Get the incoming socket associated with the given id.
uint32_t accept_reject_id
ID of the incoming request we want to reject.
Definition: seti.h:116
Operation context used to execute a set operation.
struct GNUNET_SERVICE_Client * client
Client this is about.
#define GNUNET_log(kind,...)
struct GNUNET_HashCode app_id
Application ID for the operation, used to distinguish multiple operations of the same type with the s...
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
Here is the call graph for this function:

◆ check_client_set_add()

static int check_client_set_add ( void *  cls,
const struct GNUNET_SETI_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 2045 of file gnunet-service-seti.c.

References GNUNET_OK.

2047 {
2048  /* NOTE: Technically, we should probably check with the
2049  block library whether the element we are given is well-formed */
2050  return GNUNET_OK;
2051 }

◆ handle_client_set_add()

static void handle_client_set_add ( void *  cls,
const struct GNUNET_SETI_ElementMessage msg 
)
static

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

Parameters
clsclient that sent the message
msgmessage sent by the client

Definition at line 2061 of file gnunet-service-seti.c.

References ClientState::client, GNUNET_SETI_Element::data, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SETI_Element::element_type, GNUNET_SET_Element::element_type, GNUNET_SETI_ElementMessage::element_type, 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_NO, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SETI_element_hash(), GNUNET_YES, GNUNET_SETI_ElementMessage::header, ElementEntry::remote, ClientState::set, GNUNET_SETI_Element::size, GNUNET_SET_Element::size, and GNUNET_MessageHeader::size.

2063 {
2064  struct ClientState *cs = cls;
2065  struct Set *set;
2066  struct GNUNET_SETI_Element el;
2067  struct ElementEntry *ee;
2068  struct GNUNET_HashCode hash;
2069 
2070  if (NULL == (set = cs->set))
2071  {
2072  /* client without a set requested an operation */
2073  GNUNET_break (0);
2075  return;
2076  }
2078  el.size = ntohs (msg->header.size) - sizeof(*msg);
2079  el.data = &msg[1];
2080  el.element_type = ntohs (msg->element_type);
2082  &hash);
2083  ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
2084  &hash);
2085  if (NULL == ee)
2086  {
2088  "Client inserts element %s of size %u\n",
2089  GNUNET_h2s (&hash),
2090  el.size);
2091  ee = GNUNET_malloc (el.size + sizeof(*ee));
2092  ee->element.size = el.size;
2093  GNUNET_memcpy (&ee[1], el.data, el.size);
2094  ee->element.data = &ee[1];
2095  ee->element.element_type = el.element_type;
2096  ee->remote = GNUNET_NO;
2097  ee->element_hash = hash;
2100  set->content->elements,
2101  &ee->element_hash,
2102  ee,
2104  }
2105  else
2106  {
2108  "Client inserted element %s of size %u twice (ignored)\n",
2109  GNUNET_h2s (&hash),
2110  el.size);
2111  /* same element inserted twice */
2112  return;
2113  }
2114  set->current_set_element_count++;
2115 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETI_ADD.
Definition: seti.h:231
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const void * data
Actual data of the element.
uint16_t element_type
Type of the element to add or remove.
Definition: seti.h:236
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.
Information about an element element in the set.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
A set that supports a specific operation with other peers.
Element stored in a set.
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void GNUNET_SETI_element_hash(const struct GNUNET_SETI_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: seti_api.c:875
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_SERVICE_Client * client
Client this is about.
uint16_t size
Number of bytes in the buffer pointed to by data.
#define GNUNET_log(kind,...)
struct GNUNET_SET_Element element
The actual element.
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Definition: gnunet-abd.c:51
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
#define GNUNET_malloc(size)
Wrapper around malloc.
uint16_t element_type
Application-specific element type.
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 2125 of file gnunet-service-seti.c.

References GNUNET_assert.

Referenced by handle_client_accept(), and handle_client_evaluate().

2126 {
2127  if (set->current_generation == set->content->latest_generation)
2128  {
2129  set->content->latest_generation++;
2130  set->current_generation++;
2131  return;
2132  }
2134 }
unsigned int latest_generation
FIXME: document!
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned int current_generation
Current generation, that is, number of previously executed operations and lazy copies on the underlyi...
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
Here is the caller graph for this function:

◆ check_client_evaluate()

static int check_client_evaluate ( void *  cls,
const struct GNUNET_SETI_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 2147 of file gnunet-service-seti.c.

References GNUNET_OK.

2149 {
2150  /* FIXME: suboptimal, even if the context below could be NULL,
2151  there are malformed messages this does not check for... */
2152  return GNUNET_OK;
2153 }

◆ handle_client_evaluate()

static void handle_client_evaluate ( void *  cls,
const struct GNUNET_SETI_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 2165 of file gnunet-service-seti.c.

References advance_generation(), GNUNET_SETI_EvaluateMessage::app_id, Operation::channel, channel_end_cb(), channel_window_cb(), ClientState::client, Operation::client_request_id, context, Set::current_set_element_count, OperationRequestMessage::element_count, Operation::generation_created, GNUNET_break, GNUNET_CADET_channel_create(), GNUNET_CADET_get_mq(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_P2P_BF, GNUNET_MESSAGE_TYPE_SETI_P2P_DONE, GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO, GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST, GNUNET_MQ_extract_nested_mh, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_MQ_msg_nested_mh, GNUNET_MQ_send(), GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_YES, Operation::mq, msg, Operation::my_element_count, Operation::my_elements, Operation::peer, Operation::phase, PHASE_COUNT_SENT, PHASE_INITIAL, GNUNET_SETI_EvaluateMessage::request_id, GNUNET_SETI_EvaluateMessage::return_intersection, Operation::return_intersection, Operation::salt, ClientState::set, Operation::set, and GNUNET_SETI_EvaluateMessage::target_peer.

2167 {
2168  struct ClientState *cs = cls;
2169  struct Operation *op = GNUNET_new (struct Operation);
2170  const struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
2171  GNUNET_MQ_hd_var_size (incoming_msg,
2173  struct OperationRequestMessage,
2174  op),
2175  GNUNET_MQ_hd_fixed_size (intersection_p2p_element_info,
2178  op),
2179  GNUNET_MQ_hd_var_size (intersection_p2p_bf,
2181  struct BFMessage,
2182  op),
2183  GNUNET_MQ_hd_fixed_size (intersection_p2p_done,
2185  struct IntersectionDoneMessage,
2186  op),
2188  };
2189  struct Set *set;
2190  const struct GNUNET_MessageHeader *context;
2191 
2192  if (NULL == (set = cs->set))
2193  {
2194  GNUNET_break (0);
2195  GNUNET_free (op);
2197  return;
2198  }
2200  UINT32_MAX);
2201  op->peer = msg->target_peer;
2202  op->return_intersection = htonl (msg->return_intersection);
2203  fprintf (stderr,
2204  "Return intersection for evaluate is %d\n",
2205  op->return_intersection);
2206  op->client_request_id = ntohl (msg->request_id);
2207  context = GNUNET_MQ_extract_nested_mh (msg);
2208 
2209  /* Advance generation values, so that
2210  mutations won't interfer with the running operation. */
2211  op->set = set;
2212  op->generation_created = set->current_generation;
2213  advance_generation (set);
2214  GNUNET_CONTAINER_DLL_insert (set->ops_head,
2215  set->ops_tail,
2216  op);
2218  "Creating new CADET channel to port %s for set intersection\n",
2219  GNUNET_h2s (&msg->app_id));
2221  op,
2222  &msg->target_peer,
2223  &msg->app_id,
2225  &channel_end_cb,
2226  cadet_handlers);
2227  op->mq = GNUNET_CADET_get_mq (op->channel);
2228  {
2229  struct GNUNET_MQ_Envelope *ev;
2230  struct OperationRequestMessage *msg;
2231 
2232  ev = GNUNET_MQ_msg_nested_mh (msg,
2234  context);
2235  if (NULL == ev)
2236  {
2237  /* the context message is too large!? */
2238  GNUNET_break (0);
2240  return;
2241  }
2243  "Initiating intersection operation evaluation\n");
2244  /* we started the operation, thus we have to send the operation request */
2245  op->phase = PHASE_INITIAL;
2247  op->my_elements
2249  GNUNET_YES);
2250 
2251  msg->element_count = htonl (op->my_element_count);
2252  GNUNET_MQ_send (op->mq,
2253  ev);
2254  op->phase = PHASE_COUNT_SENT;
2255  if (NULL != context)
2257  "Sent op request with context message\n");
2258  else
2260  "Sent op request without context message\n");
2261  }
2263 }
uint32_t request_id
Id of our set to evaluate, chosen implicitly by the client when it calls GNUNET_SETI_commit().
Definition: seti.h:162
struct Set * set
Set, if associated with the client, otherwise NULL.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
State we keep per client.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint32_t element_count
For Intersection: my element count.
#define GNUNET_MQ_msg_nested_mh(mvar, type, mh)
Allocate a GNUNET_MQ_Envelope, and append a payload message after the given message struct...
int return_intersection
When are elements sent to the client, and which elements are sent?
#define GNUNET_MQ_extract_nested_mh(var)
Return a pointer to the message at the end of the given message.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
We are just starting.
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
We have send the number of our elements to the other peer, but did not setup our element set yet...
static void channel_window_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int generation_created
Generation in which the operation handle was created.
static pa_context * context
Pulseaudio context.
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_HashCode app_id
Application id.
Definition: seti.h:172
A set that supports a specific operation with other peers.
Randomness for IVs etc.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO
Information about the element count for intersection.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST
Request to begin set intersection operation.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
Message handler for a specific message type.
Bloom filter messages exchanged for set intersection calculation.
Operation context used to execute a set operation.
struct GNUNET_PeerIdentity target_peer
Peer to evaluate the operation with.
Definition: seti.h:167
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
static void channel_end_cb(void *channel_ctx, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
During intersection, the first (and possibly second) message send it the number of elements in the se...
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1031
struct GNUNET_CADET_Channel * channel
Channel to the peer.
uint32_t salt
Salt to use for the operation.
struct GNUNET_SERVICE_Client * client
Client this is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_MESSAGE_TYPE_SETI_P2P_DONE
Intersection operation is done.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
uint32_t return_intersection
Return the intersection (1), instead of the elements to remove / the delta (0), in NBO...
Definition: seti.h:178
Header for all communications.
Last message, send to confirm the final set.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
#define GNUNET_MESSAGE_TYPE_SETI_P2P_BF
Bloom filter message for intersection exchange started by Bob.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1082
Here is the call graph for this function:

◆ handle_client_cancel()

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

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

Parameters
clsthe client
msgthe message

Definition at line 2273 of file gnunet-service-seti.c.

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

2275 {
2276  struct ClientState *cs = cls;
2277  struct Set *set;
2278  struct Operation *op;
2279  int found;
2280 
2281  if (NULL == (set = cs->set))
2282  {
2283  /* client without a set requested an operation */
2284  GNUNET_break (0);
2286  return;
2287  }
2288  found = GNUNET_NO;
2289  for (op = set->ops_head; NULL != op; op = op->next)
2290  {
2291  if (op->client_request_id == ntohl (msg->request_id))
2292  {
2293  found = GNUNET_YES;
2294  break;
2295  }
2296  }
2297  if (GNUNET_NO == found)
2298  {
2299  /* It may happen that the operation was already destroyed due to
2300  * the other peer disconnecting. The client may not know about this
2301  * yet and try to cancel the (just barely non-existent) operation.
2302  * So this is not a hard error.
2303  *///
2305  "Client canceled non-existent op %u\n",
2306  (uint32_t) ntohl (msg->request_id));
2307  }
2308  else
2309  {
2311  "Client requested cancel for op %u\n",
2312  (uint32_t) ntohl (msg->request_id));
2314  }
2316 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct Operation * next
Kept in a DLL of the listener, if listener is non-NULL.
uint32_t request_id
ID of the request we want to cancel.
Definition: seti.h:261
A set that supports a specific operation with other peers.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
Operation context used to execute a set operation.
struct Operation * ops_head
Evaluate operations are held in a linked list.
struct GNUNET_SERVICE_Client * client
Client this is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
Here is the call graph for this function:

◆ handle_client_accept()

static void handle_client_accept ( void *  cls,
const struct GNUNET_SETI_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 2328 of file gnunet-service-seti.c.

References GNUNET_SETI_AcceptMessage::accept_reject_id, advance_generation(), begin_bf_exchange(), Operation::channel, ClientState::client, Operation::client_request_id, Set::current_set_element_count, Operation::generation_created, get_incoming(), GNUNET_break, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_RESULT, GNUNET_MIN, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SETI_STATUS_FAILURE, GNUNET_YES, ClientState::listener, Operation::listener, Operation::my_element_count, Operation::my_elements, op, Listener::op_head, Listener::op_tail, Operation::phase, PHASE_COUNT_SENT, PHASE_INITIAL, Operation::remote_element_count, GNUNET_SETI_AcceptMessage::request_id, GNUNET_SETI_ResultMessage::request_id, GNUNET_SETI_ResultMessage::result_status, GNUNET_SETI_AcceptMessage::return_intersection, Operation::return_intersection, send_element_count(), ClientState::set, and Operation::set.

2330 {
2331  struct ClientState *cs = cls;
2332  struct Set *set;
2333  struct Operation *op;
2334  struct GNUNET_SETI_ResultMessage *result_message;
2335  struct GNUNET_MQ_Envelope *ev;
2336  struct Listener *listener;
2337 
2338  if (NULL == (set = cs->set))
2339  {
2340  /* client without a set requested to accept */
2341  GNUNET_break (0);
2343  return;
2344  }
2345  op = get_incoming (ntohl (msg->accept_reject_id));
2346  if (NULL == op)
2347  {
2348  /* It is not an error if the set op does not exist -- it may
2349  * have been destroyed when the partner peer disconnected. */
2350  GNUNET_log (
2352  "Client %p accepted request %u of listener %p that is no longer active\n",
2353  cs,
2354  ntohl (msg->accept_reject_id),
2355  cs->listener);
2356  ev = GNUNET_MQ_msg (result_message,
2358  result_message->request_id = msg->request_id;
2359  result_message->result_status = htons (GNUNET_SETI_STATUS_FAILURE);
2360  GNUNET_MQ_send (set->cs->mq, ev);
2362  return;
2363  }
2365  "Client accepting request %u\n",
2366  (uint32_t) ntohl (msg->accept_reject_id));
2367  listener = op->listener;
2368  op->listener = NULL;
2369  op->return_intersection = htonl (msg->return_intersection);
2370  fprintf (stderr,
2371  "Return intersection for accept is %d\n",
2372  op->return_intersection);
2374  listener->op_tail,
2375  op);
2376  op->set = set;
2377  GNUNET_CONTAINER_DLL_insert (set->ops_head,
2378  set->ops_tail,
2379  op);
2380  op->client_request_id = ntohl (msg->request_id);
2381 
2382  /* Advance generation values, so that future mutations do not
2383  interfer with the running operation. */
2384  op->generation_created = set->current_generation;
2385  advance_generation (set);
2386  {
2388  "Accepting set intersection operation\n");
2389  op->phase = PHASE_INITIAL;
2390  op->my_element_count
2392  op->my_elements
2395  op->remote_element_count),
2396  GNUNET_YES);
2397  if (op->remote_element_count < op->my_element_count)
2398  {
2399  /* If the other peer (Alice) has fewer elements than us (Bob),
2400  we just send the count as Alice should send the first BF */
2401  send_element_count (op);
2402  op->phase = PHASE_COUNT_SENT;
2403  }
2404  else
2405  {
2406  /* We have fewer elements, so we start with the BF */
2407  begin_bf_exchange (op);
2408  }
2409  }
2410  /* Now allow CADET to continue, as we did not do this in
2411  #handle_incoming_msg (as we wanted to first see if the
2412  local client would accept the request). */
2415 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct Set * set
Set, if associated with the client, otherwise NULL.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: seti.h:191
State we keep per client.
The other peer refused to do the operation with us, or something went wrong.
enum IntersectionOperationPhase phase
Current state of the operation.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int return_intersection
When are elements sent to the client, and which elements are sent?
struct Operation * op_head
Head of DLL of operations this listener is responsible for.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
We are just starting.
uint32_t current_set_element_count
Number of currently valid elements in the set which have not been removed.
static void begin_bf_exchange(struct Operation *op)
We go first, initialize our map with all elements and send the first Bloom filter.
static void advance_generation(struct Set *set)
Advance the current generation of a set, adding exclusion ranges if necessary.
uint32_t accept_reject_id
ID of the incoming request we want to accept.
Definition: seti.h:86
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
We have send the number of our elements to the other peer, but did not setup our element set yet...
uint32_t return_intersection
Return the intersection (1), instead of the elements to remove / the delta (0), in NBO...
Definition: seti.h:97
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int generation_created
Generation in which the operation handle was created.
static struct Operation * get_incoming(uint32_t id)
Get the incoming socket associated with the given id.
uint32_t request_id
id the result belongs to
Definition: seti.h:206
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:93
A set that supports a specific operation with other peers.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_MESSAGE_TYPE_SETI_RESULT
Handle result message from operation.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2325
uint32_t request_id
Request ID to identify responses.
Definition: seti.h:91
Operation context used to execute a set operation.
struct GNUNET_CONTAINER_MultiHashMap * my_elements
Remaining elements in the intersection operation.
uint32_t my_element_count
Current element count contained within my_elements.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct GNUNET_SERVICE_Client * client
Client this is about.
uint32_t client_request_id
ID used to identify an operation between service and client.
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETI_Status in NBO.
Definition: seti.h:212
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
struct Listener * listener
Listener, if associated with the client, otherwise NULL.
uint32_t remote_element_count
Remote peers element count.
struct Operation * op_tail
Tail of DLL of operations this listener is responsible for.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct Listener * listener
Port this operation runs on.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
static void send_element_count(struct Operation *op)
Send our element count to the peer, in case our element count is lower than theirs.
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 2424 of file gnunet-service-seti.c.

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

Referenced by run().

2425 {
2426  /* Delay actual shutdown to allow service to disconnect clients */
2428  if (0 == num_clients)
2429  {
2430  if (NULL != cadet)
2431  {
2433  cadet = NULL;
2434  }
2435  }
2437  GNUNET_YES);
2439  "handled shutdown request\n");
2440 }
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
static unsigned int num_clients
Number of active clients.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
static int in_shutdown
Are we in shutdown? if GNUNET_YES and the number of clients drops to zero, disconnect from CADET...
#define GNUNET_log(kind,...)
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
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 2452 of file gnunet-service-seti.c.

References _, client_connect_cb(), client_disconnect_cb(), GNUNET_CADET_connect(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MESSAGE_TYPE_SETI_ACCEPT, GNUNET_MESSAGE_TYPE_SETI_ADD, GNUNET_MESSAGE_TYPE_SETI_CANCEL, GNUNET_MESSAGE_TYPE_SETI_CREATE, GNUNET_MESSAGE_TYPE_SETI_EVALUATE, GNUNET_MESSAGE_TYPE_SETI_LISTEN, GNUNET_MESSAGE_TYPE_SETI_REJECT, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_NONE, GNUNET_STATISTICS_create(), and shutdown_task().

2455 {
2456  /* FIXME: need to modify SERVICE (!) API to allow
2457  us to run a shutdown task *after* clients were
2458  forcefully disconnected! */
2460  NULL);
2462  cfg);
2463  cadet = GNUNET_CADET_connect (cfg);
2464  if (NULL == cadet)
2465  {
2467  _ ("Could not connect to CADET service\n"));
2469  return;
2470  }
2471 }
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:910
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
static void shutdown_task(void *cls)
Called to clean up, after a shutdown has been requested.
#define GNUNET_log(kind,...)
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

Define "main" method using service macro.

Referenced by run().

Here is the caller graph for this function:

Variable Documentation

◆ cadet

struct GNUNET_CADET_Handle* cadet
static

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

Definition at line 471 of file gnunet-service-seti.c.

◆ _GSS_statistics

struct GNUNET_STATISTICS_Handle* _GSS_statistics
static

Statistics handle.

Definition at line 476 of file gnunet-service-seti.c.

◆ listener_head

struct Listener* listener_head
static

Listeners are held in a doubly linked list.

Definition at line 481 of file gnunet-service-seti.c.

◆ listener_tail

struct Listener* listener_tail
static

Listeners are held in a doubly linked list.

Definition at line 486 of file gnunet-service-seti.c.

◆ num_clients

unsigned int num_clients
static

Number of active clients.

Definition at line 491 of file gnunet-service-seti.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 497 of file gnunet-service-seti.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 505 of file gnunet-service-seti.c.

Referenced by handle_incoming_msg().