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

set union operation More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_statistics_service.h"
#include "ibf.h"
#include "gnunet_protocols.h"
#include "gnunet_applications.h"
#include "gnunet_cadet_service.h"
#include "gnunet-service-setu_strata_estimator.h"
#include "gnunet-service-setu_protocol.h"
#include <gcrypt.h>
#include "gnunet_setu_service.h"
#include "setu.h"
Include dependency graph for gnunet-service-setu.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  KeyEntry
 The key entry is used to associate an ibf key with an element. More...
 
struct  SendElementClosure
 Used as a closure for sending elements with a specific IBF key. More...
 
struct  Listener
 A listener is inhabited by a client, and waits for evaluation requests from remote peers. More...
 
struct  GetElementContext
 Context for op_get_element_iterator. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "setu", __VA_ARGS__)
 
#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...
 
#define SE_STRATA_COUNT   32
 Number of IBFs in a strata estimator. More...
 
#define SE_IBF_SIZE   80
 Size of the IBFs in the strata estimator. More...
 
#define SE_IBF_HASH_NUM   4
 The hash num parameter for the difference digests and strata estimators. More...
 
#define MAX_BUCKETS_PER_MESSAGE   ((1 << 15) / IBF_BUCKET_SIZE)
 Number of buckets that can be transmitted in one message. More...
 
#define MAX_IBF_ORDER   (20)
 The maximum size of an ibf we use is 2^(MAX_IBF_ORDER). More...
 
#define IBF_ALPHA   4
 Number of buckets used in the ibf per estimated difference. More...
 

Enumerations

enum  UnionOperationPhase {
  PHASE_EXPECT_SE, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_ACTIVE,
  PHASE_INVENTORY_PASSIVE, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, PHASE_DONE,
  PHASE_FULL_SENDING, PHASE_EXPECT_SE, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_LAST,
  PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING,
  PHASE_FINISHED, PHASE_FULL_SENDING, PHASE_FULL_RECEIVING
}
 Current phase we are in for a union operation. More...
 

Functions

static int destroy_key_to_element_iter (void *cls, uint32_t key, void *value)
 Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries. More...
 
static void send_client_done (void *cls)
 Signal to the client that the operation has finished and destroy the operation. 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 fail_union_operation (struct Operation *op)
 Inform the client that the union operation has failed, and proceed to destroy the evaluate operation. More...
 
static struct IBF_Key get_ibf_key (const struct GNUNET_HashCode *src)
 Derive the IBF key from a hash code and a salt. More...
 
static int op_get_element_iterator (void *cls, uint32_t key, void *value)
 Iterator over the mapping from IBF keys to element entries. More...
 
static struct KeyEntryop_get_element (struct Operation *op, const struct GNUNET_HashCode *element_hash)
 Determine whether the given element is already in the operation's element set. More...
 
static void op_register_element (struct Operation *op, struct ElementEntry *ee, int received)
 Insert an element into the union operation's key-to-element mapping. More...
 
static void salt_key (const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
 Modify an IBF key k_in based on the salt, returning a salted key in k_out. More...
 
static void unsalt_key (const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
 FIXME. More...
 
static int prepare_ibf_iterator (void *cls, uint32_t key, void *value)
 Insert a key into an ibf. 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 init_key_to_element_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator for initializing the key-to-element mapping of a union operation. More...
 
static void initialize_key_to_element (struct Operation *op)
 Initialize the IBF key to element mapping local to this set operation. More...
 
static int prepare_ibf (struct Operation *op, uint32_t size)
 Create an ibf with the operation's elements of the specified size. More...
 
static int send_ibf (struct Operation *op, uint16_t ibf_order)
 Send an ibf of appropriate size. More...
 
static unsigned int get_order_from_difference (unsigned int diff)
 Compute the necessary order of an ibf from the size of the symmetric set difference. More...
 
static int send_full_element_iterator (void *cls, const struct GNUNET_HashCode *key, void *value)
 Send a set element. More...
 
static void send_full_set (struct Operation *op)
 Switch to full set transmission for op. More...
 
static int check_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
static void handle_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
static int send_offers_iterator (void *cls, uint32_t key, void *value)
 Iterator to send elements to a remote peer. More...
 
static void send_offers_for_key (struct Operation *op, struct IBF_Key ibf_key)
 Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key. More...
 
static int decode_and_send (struct Operation *op)
 Decode which elements are missing on each side, and send the appropriate offers and inquiries. More...
 
static int check_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Check an IBF message from a remote peer. More...
 
static void handle_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Handle an IBF message from a remote peer. More...
 
static void send_client_element (struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
 Send a result message to the client indicating that there is a new element. More...
 
static void maybe_finish (struct Operation *op)
 Tests if the operation is finished, and if so notify. More...
 
static int check_union_p2p_elements (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Check an element message from a remote peer. More...
 
static void handle_union_p2p_elements (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
static int check_union_p2p_full_element (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Check a full element message from a remote peer. More...
 
static void handle_union_p2p_full_element (void *cls, const struct GNUNET_SETU_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
static int check_union_p2p_inquiry (void *cls, const struct InquiryMessage *msg)
 Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s). More...
 
static void handle_union_p2p_inquiry (void *cls, const struct InquiryMessage *msg)
 Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s). More...
 
static int send_missing_full_elements_iter (void *cls, uint32_t key, void *value)
 Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries. More...
 
static void handle_union_p2p_request_full (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a request for full set transmission. More...
 
static void handle_union_p2p_full_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a "full done" message. More...
 
static int check_union_p2p_demand (void *cls, const struct GNUNET_MessageHeader *mh)
 Check a demand by the other peer for elements based on a list of struct GNUNET_HashCodes. More...
 
static void handle_union_p2p_demand (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a demand by the other peer for elements based on a list of struct GNUNET_HashCodes. More...
 
static int check_union_p2p_offer (void *cls, const struct GNUNET_MessageHeader *mh)
 Check offer (of struct GNUNET_HashCodes). More...
 
static void handle_union_p2p_offer (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle offers (of struct GNUNET_HashCodes) and respond with demands (of struct GNUNET_HashCodes). More...
 
static void handle_union_p2p_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a done message from a remote peer. More...
 
static void handle_union_p2p_over (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a over 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_SETU_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_SETU_ListenMessage *msg)
 Called when a client wants to create a new listener. More...
 
static void handle_client_reject (void *cls, const struct GNUNET_SETU_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_SETU_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_SETU_ElementMessage *msg)
 Called when a client wants to add or remove an element to a set it inhabits. More...
 
static void advance_generation (struct Set *set)
 Advance the current generation of a set, adding exclusion ranges if necessary. More...
 
static int check_client_evaluate (void *cls, const struct GNUNET_SETU_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_SETU_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_SETU_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_SETU_AcceptMessage *msg)
 Handle a request from the client to accept a set operation that came from a remote peer. More...
 
static void shutdown_task (void *cls)
 Called to clean up, after a shutdown has been requested. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
 Function called by the service's run method to run service-specific setup code. More...
 
 GNUNET_SERVICE_MAIN ("set", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(client_accept, GNUNET_MESSAGE_TYPE_SETU_ACCEPT, struct GNUNET_SETU_AcceptMessage, NULL), GNUNET_MQ_hd_var_size(client_set_add, GNUNET_MESSAGE_TYPE_SETU_ADD, struct GNUNET_SETU_ElementMessage, NULL), GNUNET_MQ_hd_fixed_size(client_create_set, GNUNET_MESSAGE_TYPE_SETU_CREATE, struct GNUNET_SETU_CreateMessage, NULL), GNUNET_MQ_hd_var_size(client_evaluate, GNUNET_MESSAGE_TYPE_SETU_EVALUATE, struct GNUNET_SETU_EvaluateMessage, NULL), GNUNET_MQ_hd_fixed_size(client_listen, GNUNET_MESSAGE_TYPE_SETU_LISTEN, struct GNUNET_SETU_ListenMessage, NULL), GNUNET_MQ_hd_fixed_size(client_reject, GNUNET_MESSAGE_TYPE_SETU_REJECT, struct GNUNET_SETU_RejectMessage, NULL), GNUNET_MQ_hd_fixed_size(client_cancel, GNUNET_MESSAGE_TYPE_SETU_CANCEL, struct GNUNET_SETU_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...
 

Detailed Description

set union operation

Author
Florian Dold
Christian Grothoff

Definition in file gnunet-service-setu.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "setu", __VA_ARGS__)

◆ 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 46 of file gnunet-service-setu.c.

Referenced by channel_new_cb().

◆ SE_STRATA_COUNT

#define SE_STRATA_COUNT   32

Number of IBFs in a strata estimator.

Definition at line 51 of file gnunet-service-setu.c.

Referenced by check_union_p2p_strata_estimator(), handle_client_create_set(), and handle_union_p2p_strata_estimator().

◆ SE_IBF_SIZE

#define SE_IBF_SIZE   80

Size of the IBFs in the strata estimator.

Definition at line 56 of file gnunet-service-setu.c.

Referenced by check_union_p2p_strata_estimator(), handle_client_create_set(), and handle_union_p2p_strata_estimator().

◆ SE_IBF_HASH_NUM

#define SE_IBF_HASH_NUM   4

The hash num parameter for the difference digests and strata estimators.

Definition at line 61 of file gnunet-service-setu.c.

Referenced by get_order_from_difference(), handle_client_create_set(), handle_union_p2p_ibf(), handle_union_p2p_strata_estimator(), and prepare_ibf().

◆ MAX_BUCKETS_PER_MESSAGE

#define MAX_BUCKETS_PER_MESSAGE   ((1 << 15) / IBF_BUCKET_SIZE)

Number of buckets that can be transmitted in one message.

Definition at line 66 of file gnunet-service-setu.c.

Referenced by send_ibf().

◆ MAX_IBF_ORDER

#define MAX_IBF_ORDER   (20)

The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).

Choose this value so that computing the IBF is still cheaper than transmitting all values.

Definition at line 73 of file gnunet-service-setu.c.

Referenced by decode_and_send(), and get_order_from_difference().

◆ IBF_ALPHA

#define IBF_ALPHA   4

Number of buckets used in the ibf per estimated difference.

Definition at line 79 of file gnunet-service-setu.c.

Referenced by get_order_from_difference().

Enumeration Type Documentation

◆ UnionOperationPhase

Current phase we are in for a union operation.

Enumerator
PHASE_EXPECT_SE 

We sent the request message, and expect a strata estimator.

PHASE_EXPECT_IBF 

We sent the strata estimator, and expect an IBF.

This phase is entered once upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS.

XXX: could use better wording. XXX: repurposed to also expect a "request full set" message, should be renamed

After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS

PHASE_EXPECT_IBF_CONT 

Continuation for multi part IBFs.

PHASE_INVENTORY_ACTIVE 

We are decoding an IBF.

PHASE_INVENTORY_PASSIVE 

The other peer is decoding the IBF we just sent.

PHASE_FINISH_CLOSING 

The protocol is almost finished, but we still have to flush our message queue and/or expect some elements.

PHASE_FINISH_WAITING 

In the penultimate phase, we wait until all our demands are satisfied.

Then we send a done message, and wait for another done message.

PHASE_DONE 

In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE message).

PHASE_FULL_SENDING 

After sending the full set, wait for responses with the elements that the local peer is missing.

PHASE_EXPECT_SE 

We sent the request message, and expect a strata estimator.

PHASE_EXPECT_IBF 

We sent the strata estimator, and expect an IBF.

This phase is entered once upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS.

XXX: could use better wording. XXX: repurposed to also expect a "request full set" message, should be renamed

After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS

PHASE_EXPECT_IBF_LAST 

Continuation for multi part IBFs.

PHASE_ACTIVE_DECODING 

We are decoding an IBF.

PHASE_PASSIVE_DECODING 

The other peer is decoding the IBF we just sent.

PHASE_FINISH_CLOSING 

The protocol is almost finished, but we still have to flush our message queue and/or expect some elements.

PHASE_FINISH_WAITING 

In the penultimate phase, we wait until all our demands are satisfied.

Then we send a done message, and wait for another done message.

PHASE_FINISHED 

In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE message).

PHASE_FULL_SENDING 

After sending the full set, wait for responses with the elements that the local peer is missing.

PHASE_FULL_RECEIVING 

Phase that receives full set first and then sends elements that are the local peer missing.

Definition at line 85 of file gnunet-service-setu.c.

86 {
91 
102 
107 
112 
117 
123 
129 
135 
141 
147 };
After sending the full set, wait for responses with the elements that the local peer is missing...
The other peer is decoding the IBF we just sent.
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
We sent the strata estimator, and expect an IBF.
Continuation for multi part IBFs.
In the penultimate phase, we wait until all our demands are satisfied.
We are decoding an IBF.
Phase that receives full set first and then sends elements that are the local peer missing...
We sent the request message, and expect a strata estimator.

Function Documentation

◆ destroy_key_to_element_iter()

static int destroy_key_to_element_iter ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries.

Parameters
clsclosure
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 634 of file gnunet-service-setu.c.

References KeyEntry::element, GNUNET_assert, GNUNET_free, GNUNET_YES, ElementEntry::remote, and value.

Referenced by _GSS_operation_destroy().

637 {
638  struct KeyEntry *k = value;
639 
640  GNUNET_assert (NULL != k);
641  if (GNUNET_YES == k->element->remote)
642  {
643  GNUNET_free (k->element);
644  k->element = NULL;
645  }
646  GNUNET_free (k);
647  return GNUNET_YES;
648 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
struct ElementEntry * element
The actual element associated with the key.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ send_client_done()

static void send_client_done ( void *  cls)
static

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

Parameters
clsoperation to destroy

Definition at line 658 of file gnunet-service-setu.c.

References Operation::client_done_sent, Operation::client_request_id, Set::cs, GNUNET_SETU_ResultMessage::current_size, GNUNET_SETU_ResultMessage::element_type, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_htonll(), GNUNET_MESSAGE_TYPE_SETU_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SETU_STATUS_DONE, GNUNET_SETU_STATUS_FAILURE, GNUNET_STATISTICS_update(), GNUNET_YES, Operation::key_to_element, LOG, ClientState::mq, op, Operation::phase, PHASE_FINISHED, GNUNET_SETU_ResultMessage::request_id, GNUNET_SETU_ResultMessage::result_status, and Operation::set.

Referenced by _GSS_operation_destroy2(), handle_union_p2p_full_done(), handle_union_p2p_over(), and maybe_finish().

659 {
660  struct Operation *op = cls;
661  struct GNUNET_MQ_Envelope *ev;
662  struct GNUNET_SETU_ResultMessage *rm;
663 
664  if (GNUNET_YES == op->client_done_sent)
665  return;
666  if (PHASE_FINISHED != op->phase)
667  {
669  "Union operation failed\n");
671  "# Union operations failed",
672  1,
673  GNUNET_NO);
676  rm->request_id = htonl (op->client_request_id);
677  rm->element_type = htons (0);
678  GNUNET_MQ_send (op->set->cs->mq,
679  ev);
680  return;
681  }
682 
684 
686  "# Union operations succeeded",
687  1,
688  GNUNET_NO);
690  "Signalling client that union operation is done\n");
691  ev = GNUNET_MQ_msg (rm,
693  rm->request_id = htonl (op->client_request_id);
695  rm->element_type = htons (0);
697  op->key_to_element));
698  GNUNET_MQ_send (op->set->cs->mq,
699  ev);
700 }
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t request_id
id the result belongs to
Definition: setu.h:254
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: setu.h:265
The other peer refused to do the operation with us, or something went wrong.
#define GNUNET_MESSAGE_TYPE_SETU_RESULT
Handle result message from operation.
Success, all elements have been sent (and received).
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETU_Status in NBO.
Definition: setu.h:260
#define LOG(kind,...)
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
uint64_t current_size
Current set size.
Definition: setu.h:249
struct ClientState * cs
Client that owns the set.
int client_done_sent
Did we send the client that we are done?
Operation context used to execute a set operation.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: setu.h:239
uint32_t client_request_id
ID used to identify an operation between service and client.
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
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 718 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), Operation::channel, Operation::context_msg, Operation::demanded_hashes, destroy_key_to_element_iter(), GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap32_destroy(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, ibf_destroy(), Operation::key_to_element, Operation::listener, Operation::local_ibf, op, Operation::remote_ibf, Operation::se, Operation::set, and strata_estimator_destroy().

Referenced by _GSS_operation_destroy2(), client_disconnect_cb(), fail_union_operation(), and handle_client_cancel().

719 {
720  struct Set *set = op->set;
721  struct GNUNET_CADET_Channel *channel;
722 
724  "Destroying union operation %p\n",
725  op);
726  GNUNET_assert (NULL == op->listener);
727  /* check if the op was canceled twice */
728  if (NULL != op->remote_ibf)
729  {
730  ibf_destroy (op->remote_ibf);
731  op->remote_ibf = NULL;
732  }
733  if (NULL != op->demanded_hashes)
734  {
736  op->demanded_hashes = NULL;
737  }
738  if (NULL != op->local_ibf)
739  {
740  ibf_destroy (op->local_ibf);
741  op->local_ibf = NULL;
742  }
743  if (NULL != op->se)
744  {
746  op->se = NULL;
747  }
748  if (NULL != op->key_to_element)
749  {
752  NULL);
754  op->key_to_element = NULL;
755  }
756  if (NULL != set)
757  {
758  GNUNET_CONTAINER_DLL_remove (set->ops_head,
759  set->ops_tail,
760  op);
761  op->set = NULL;
762  }
763  if (NULL != op->context_msg)
764  {
765  GNUNET_free (op->context_msg);
766  op->context_msg = NULL;
767  }
768  if (NULL != (channel = op->channel))
769  {
770  /* This will free op; called conditionally as this helper function
771  is also called from within the channel disconnect handler. */
772  op->channel = NULL;
774  }
775  /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
776  * there was a channel end handler that will free 'op' on the call stack. */
777 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
struct GNUNET_MessageHeader * context_msg
Context message, may be NULL.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Opaque handle to a channel.
Definition: cadet.h:116
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
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...
static int destroy_key_to_element_iter(void *cls, uint32_t key, void *value)
Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries...
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:403
struct GNUNET_CADET_Channel * channel
Channel to the peer.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_log(kind,...)
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.
#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 824 of file gnunet-service-setu.c.

References _GSS_operation_destroy(), Operation::channel, GNUNET_CADET_channel_destroy(), GNUNET_free, incoming_destroy(), Operation::listener, send_client_done(), and Operation::set.

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

825 {
826  struct GNUNET_CADET_Channel *channel;
827 
828  if (NULL != (channel = op->channel))
829  {
830  /* This will free op; called conditionally as this helper function
831  is also called from within the channel disconnect handler. */
832  op->channel = NULL;
834  }
835  if (NULL != op->listener)
836  {
837  incoming_destroy (op);
838  return;
839  }
840  if (NULL != op->set)
841  send_client_done (op);
843  GNUNET_free (op);
844 }
Opaque handle to a channel.
Definition: cadet.h:116
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
struct GNUNET_CADET_Channel * channel
Channel to the 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.
#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 795 of file gnunet-service-setu.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().

796 {
797  struct Listener *listener;
798 
800  "Destroying incoming operation %p\n",
801  op);
802  if (NULL != (listener = op->listener))
803  {
805  listener->op_tail,
806  op);
807  op->listener = NULL;
808  }
809  if (NULL != op->timeout_task)
810  {
812  op->timeout_task = NULL;
813  }
815 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
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 void _GSS_operation_destroy2(struct Operation *op)
This function probably should not exist and be replaced by inlining more specific logic in the variou...
struct GNUNET_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:

◆ fail_union_operation()

static void fail_union_operation ( struct Operation op)
static

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

Parameters
opthe union operation to fail

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

References _GSS_operation_destroy(), Operation::client_request_id, Set::cs, GNUNET_SETU_ResultMessage::element_type, GNUNET_ERROR_TYPE_WARNING, GNUNET_MESSAGE_TYPE_SETU_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SETU_STATUS_FAILURE, LOG, ClientState::mq, msg, GNUNET_SETU_ResultMessage::request_id, GNUNET_SETU_ResultMessage::result_status, and Operation::set.

Referenced by decode_and_send(), handle_union_p2p_demand(), handle_union_p2p_done(), handle_union_p2p_elements(), handle_union_p2p_full_done(), handle_union_p2p_full_element(), handle_union_p2p_ibf(), handle_union_p2p_request_full(), and handle_union_p2p_strata_estimator().

855 {
856  struct GNUNET_MQ_Envelope *ev;
858 
860  "union operation failed\n");
863  msg->request_id = htonl (op->client_request_id);
864  msg->element_type = htons (0);
865  GNUNET_MQ_send (op->set->cs->mq,
866  ev);
868 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
uint32_t request_id
id the result belongs to
Definition: setu.h:254
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: setu.h:265
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
The other peer refused to do the operation with us, or something went wrong.
#define GNUNET_MESSAGE_TYPE_SETU_RESULT
Handle result message from operation.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETU_Status in NBO.
Definition: setu.h:260
#define LOG(kind,...)
struct ClientState * cs
Client that owns the set.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: setu.h:239
uint32_t client_request_id
ID used to identify an operation between service and client.
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_ibf_key()

static struct IBF_Key get_ibf_key ( const struct GNUNET_HashCode src)
static

Derive the IBF key from a hash code and a salt.

Parameters
srcthe hash code
Returns
the derived IBF key

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

References GNUNET_assert, GNUNET_CRYPTO_kdf(), GNUNET_OK, key, and salt.

Referenced by handle_client_set_add(), op_get_element(), and op_register_element().

880 {
881  struct IBF_Key key;
882  uint16_t salt = 0;
883 
885  GNUNET_CRYPTO_kdf (&key, sizeof(key),
886  src, sizeof *src,
887  &salt, sizeof(salt),
888  NULL, 0));
889  return key;
890 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:90
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ op_get_element_iterator()

static int op_get_element_iterator ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator over the mapping from IBF keys to element entries.

Checks if we have an element with a given GNUNET_HashCode.

Parameters
clsclosure
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES if we should search further, GNUNET_NO if we've found the element.

Definition at line 921 of file gnunet-service-setu.c.

References ctx, KeyEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_CRYPTO_hash_cmp(), GNUNET_NO, GNUNET_YES, GetElementContext::hash, GetElementContext::k, and value.

Referenced by op_get_element().

924 {
925  struct GetElementContext *ctx = cls;
926  struct KeyEntry *k = value;
927 
928  GNUNET_assert (NULL != k);
930  &ctx->hash))
931  {
932  ctx->k = k;
933  return GNUNET_NO;
934  }
935  return GNUNET_YES;
936 }
Context for op_get_element_iterator.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct KeyEntry * k
FIXME.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
struct ElementEntry * element
The actual element associated with the key.
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:201
struct GNUNET_HashCode hash
FIXME.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ op_get_element()

static struct KeyEntry* op_get_element ( struct Operation op,
const struct GNUNET_HashCode element_hash 
)
static

Determine whether the given element is already in the operation's element set.

Parameters
opoperation that should be tested for 'element_hash'
element_hashhash of the element to look for
Returns
GNUNET_YES if the element has been found, GNUNET_NO otherwise

Definition at line 948 of file gnunet-service-setu.c.

References ElementEntry::element_hash, get_ibf_key(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_get_multiple(), GNUNET_SYSERR, GetElementContext::hash, GetElementContext::k, Operation::key_to_element, IBF_Key::key_val, op_get_element_iterator(), and ret.

Referenced by handle_union_p2p_elements(), and handle_union_p2p_full_element().

950 {
951  int ret;
952  struct IBF_Key ibf_key;
953  struct GetElementContext ctx = { { { 0 } }, 0 };
954 
955  ctx.hash = *element_hash;
956 
957  ibf_key = get_ibf_key (element_hash);
959  (uint32_t) ibf_key.key_val,
961  &ctx);
962 
963  /* was the iteration aborted because we found the element? */
964  if (GNUNET_SYSERR == ret)
965  {
966  GNUNET_assert (NULL != ctx.k);
967  return ctx.k;
968  }
969  return NULL;
970 }
Context for op_get_element_iterator.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct KeyEntry * k
FIXME.
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
static int op_get_element_iterator(void *cls, uint32_t key, void *value)
Iterator over the mapping from IBF keys to element entries.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
struct GNUNET_HashCode hash
FIXME.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ op_register_element()

static void op_register_element ( struct Operation op,
struct ElementEntry ee,
int  received 
)
static

Insert an element into the union operation's key-to-element mapping.

Takes ownership of 'ee'. Note that this does not insert the element in the set, only in the operation's key-element mapping. This is done to speed up re-tried operations, if some elements were transmitted, and then the IBF fails to decode.

XXX: clarify ownership, doesn't sound right.

Parameters
opthe union operation
eethe element entry received was this element received from the remote peer?

Definition at line 988 of file gnunet-service-setu.c.

References KeyEntry::element, ElementEntry::element_hash, get_ibf_key(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_new, GNUNET_OK, KeyEntry::ibf_key, Operation::key_to_element, IBF_Key::key_val, and KeyEntry::received.

Referenced by handle_union_p2p_elements(), handle_union_p2p_full_element(), and init_key_to_element_iterator().

991 {
992  struct IBF_Key ibf_key;
993  struct KeyEntry *k;
994 
996  k = GNUNET_new (struct KeyEntry);
997  k->element = ee;
998  k->ibf_key = ibf_key;
999  k->received = received;
1002  (uint32_t) ibf_key.key_val,
1003  k,
1005 }
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint64_t key_val
Definition: ibf.h:47
int GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
The key entry is used to associate an ibf key with an element.
static struct IBF_Key get_ibf_key(const struct GNUNET_HashCode *src)
Derive the IBF key from a hash code and a salt.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
struct ElementEntry * element
The actual element associated with the key.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
Allow multiple values with the same key.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ salt_key()

static void salt_key ( const struct IBF_Key k_in,
uint32_t  salt,
struct IBF_Key k_out 
)
static

Modify an IBF key k_in based on the salt, returning a salted key in k_out.

Definition at line 1013 of file gnunet-service-setu.c.

References IBF_Key::key_val.

Referenced by prepare_ibf_iterator().

1016 {
1017  int s = salt % 64;
1018  uint64_t x = k_in->key_val;
1019 
1020  /* rotate ibf key */
1021  x = (x >> s) | (x << (64 - s));
1022  k_out->key_val = x;
1023 }
uint64_t key_val
Definition: ibf.h:47
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Here is the caller graph for this function:

◆ unsalt_key()

static void unsalt_key ( const struct IBF_Key k_in,
uint32_t  salt,
struct IBF_Key k_out 
)
static

FIXME.

Definition at line 1030 of file gnunet-service-setu.c.

References IBF_Key::key_val.

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

1033 {
1034  int s = salt % 64;
1035  uint64_t x = k_in->key_val;
1036 
1037  x = (x << s) | (x >> (64 - s));
1038  k_out->key_val = x;
1039 }
uint64_t key_val
Definition: ibf.h:47
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Here is the caller graph for this function:

◆ prepare_ibf_iterator()

static int prepare_ibf_iterator ( void *  cls,
uint32_t  key,
void *  value 
)
static

Insert a key into an ibf.

Parameters
clsthe ibf
keyunused
valuethe key entry to get the key from

Definition at line 1050 of file gnunet-service-setu.c.

References KeyEntry::element, ElementEntry::element_hash, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_YES, ibf_insert(), KeyEntry::ibf_key, IBF_Key::key_val, Operation::local_ibf, LOG, salt_key(), Operation::salt_send, and value.

Referenced by prepare_ibf().

1053 {
1054  struct Operation *op = cls;
1055  struct KeyEntry *ke = value;
1056  struct IBF_Key salted_key;
1057 
1059  "[OP %p] inserting %lx (hash %s) into ibf\n",
1060  op,
1061  (unsigned long) ke->ibf_key.key_val,
1062  GNUNET_h2s (&ke->element->element_hash));
1063  salt_key (&ke->ibf_key,
1064  op->salt_send,
1065  &salted_key);
1066  ibf_insert (op->local_ibf, salted_key);
1067  return GNUNET_YES;
1068 }
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).
uint64_t key_val
Definition: ibf.h:47
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
struct ElementEntry * element
The actual element associated with the key.
static void salt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
Modify an IBF key k_in based on the salt, returning a salted key in k_out.
#define LOG(kind,...)
Operation context used to execute a set operation.
void ibf_insert(struct InvertibleBloomFilter *ibf, struct IBF_Key key)
Insert a key into an IBF.
Definition: ibf.c:167
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
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 1079 of file gnunet-service-setu.c.

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

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

1081 {
1082  return ee->generation >= op->generation_created;
1083 }
unsigned int generation_created
Generation in which the operation handle was created.
unsigned int generation
First generation that includes this element.
Here is the caller graph for this function:

◆ init_key_to_element_iterator()

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

Iterator for initializing the key-to-element mapping of a union operation.

Parameters
clsthe union operation struct Operation *
keyunused
valuethe struct ElementEntry * to insert into the key-to-element mapping
Returns
GNUNET_YES (to continue iterating)

Definition at line 1097 of file gnunet-service-setu.c.

References _GSS_is_element_of_operation(), GNUNET_assert, GNUNET_NO, GNUNET_YES, op_register_element(), ElementEntry::remote, and value.

Referenced by initialize_key_to_element().

1100 {
1101  struct Operation *op = cls;
1102  struct ElementEntry *ee = value;
1103 
1104  /* make sure that the element belongs to the set at the time
1105  * of creating the operation */
1106  if (GNUNET_NO ==
1108  op))
1109  return GNUNET_YES;
1110  GNUNET_assert (GNUNET_NO == ee->remote);
1111  op_register_element (op,
1112  ee,
1113  GNUNET_NO);
1114  return GNUNET_YES;
1115 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char * value
Value of the record to add/remove.
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...
Operation context used to execute a set operation.
static void op_register_element(struct Operation *op, struct ElementEntry *ee, int received)
Insert an element into the union operation&#39;s key-to-element mapping.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_key_to_element()

static void initialize_key_to_element ( struct Operation op)
static

Initialize the IBF key to element mapping local to this set operation.

Parameters
opthe set union operation

Definition at line 1124 of file gnunet-service-setu.c.

References Set::content, SetContent::elements, GNUNET_assert, GNUNET_CONTAINER_multihashmap32_create(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_size(), init_key_to_element_iterator(), Operation::key_to_element, len, and Operation::set.

Referenced by handle_client_accept(), and handle_client_evaluate().

1125 {
1126  unsigned int len;
1127 
1128  GNUNET_assert (NULL == op->key_to_element);
1133  op);
1134 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int init_key_to_element_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator for initializing the key-to-element mapping of a union 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...
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
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.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_ibf()

static int prepare_ibf ( struct Operation op,
uint32_t  size 
)
static

Create an ibf with the operation's elements of the specified size.

Parameters
opthe union operation
sizesize of the ibf to create
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1146 of file gnunet-service-setu.c.

References GNUNET_assert, GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, ibf_create(), ibf_destroy(), Operation::key_to_element, Operation::local_ibf, prepare_ibf_iterator(), and SE_IBF_HASH_NUM.

Referenced by decode_and_send(), and send_ibf().

1148 {
1149  GNUNET_assert (NULL != op->key_to_element);
1150 
1151  if (NULL != op->local_ibf)
1152  ibf_destroy (op->local_ibf);
1154  if (NULL == op->local_ibf)
1155  {
1157  "Failed to allocate local IBF\n");
1158  return GNUNET_SYSERR;
1159  }
1162  op);
1163  return GNUNET_OK;
1164 }
static int prepare_ibf_iterator(void *cls, uint32_t key, void *value)
Insert a key into an ibf.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:403
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:79
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_log(kind,...)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_ibf()

static int send_ibf ( struct Operation op,
uint16_t  ibf_order 
)
static

Send an ibf of appropriate size.

Fragments the IBF into multiple messages if necessary.

Parameters
opthe union operation
ibf_orderorder of the ibf to send, size=2^order
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1177 of file gnunet-service-setu.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SETU_P2P_IBF, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, IBF_BUCKET_SIZE, ibf_write_slice(), Operation::local_ibf, LOG, MAX_BUCKETS_PER_MESSAGE, Operation::mq, msg, name, IBFMessage::offset, IBFMessage::order, Operation::phase, PHASE_PASSIVE_DECODING, prepare_ibf(), IBFMessage::reserved1, IBFMessage::reserved2, IBFMessage::salt, and Operation::salt_send.

Referenced by decode_and_send(), and handle_union_p2p_strata_estimator().

1179 {
1180  unsigned int buckets_sent = 0;
1181  struct InvertibleBloomFilter *ibf;
1182 
1183  if (GNUNET_OK !=
1184  prepare_ibf (op, 1 << ibf_order))
1185  {
1186  /* allocation failed */
1187  return GNUNET_SYSERR;
1188  }
1189 
1191  "sending ibf of size %u\n",
1192  1 << ibf_order);
1193 
1194  {
1195  char name[64] = { 0 };
1196  snprintf (name, sizeof(name), "# sent IBF (order %u)", ibf_order);
1198  }
1199 
1200  ibf = op->local_ibf;
1201 
1202  while (buckets_sent < (1 << ibf_order))
1203  {
1204  unsigned int buckets_in_message;
1205  struct GNUNET_MQ_Envelope *ev;
1206  struct IBFMessage *msg;
1207 
1208  buckets_in_message = (1 << ibf_order) - buckets_sent;
1209  /* limit to maximum */
1210  if (buckets_in_message > MAX_BUCKETS_PER_MESSAGE)
1211  buckets_in_message = MAX_BUCKETS_PER_MESSAGE;
1212 
1213  ev = GNUNET_MQ_msg_extra (msg,
1214  buckets_in_message * IBF_BUCKET_SIZE,
1216  msg->reserved1 = 0;
1217  msg->reserved2 = 0;
1218  msg->order = ibf_order;
1219  msg->offset = htonl (buckets_sent);
1220  msg->salt = htonl (op->salt_send);
1221  ibf_write_slice (ibf, buckets_sent,
1222  buckets_in_message, &msg[1]);
1223  buckets_sent += buckets_in_message;
1225  "ibf chunk size %u, %u/%u sent\n",
1226  buckets_in_message,
1227  buckets_sent,
1228  1 << ibf_order);
1229  GNUNET_MQ_send (op->mq, ev);
1230  }
1231 
1232  /* The other peer must decode the IBF, so
1233  * we're passive. */
1235  return GNUNET_OK;
1236 }
uint32_t offset
Offset of the strata in the rest of the message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum IntersectionOperationPhase phase
Current state of the operation.
uint8_t reserved1
Padding, must be 0.
Message containing buckets of an invertible bloom filter.
The other peer is decoding the IBF we just sent.
Invertible bloom filter (IBF).
Definition: ibf.h:82
void ibf_write_slice(const struct InvertibleBloomFilter *ibf, uint32_t start, uint32_t count, void *buf)
Write buckets from an ibf to a buffer.
Definition: ibf.c:290
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_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
#define MAX_BUCKETS_PER_MESSAGE
Number of buckets that can be transmitted in one message.
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
#define LOG(kind,...)
uint16_t reserved2
Padding, must be 0.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
uint32_t salt
Salt used when hashing elements for this IBF.
const char * name
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_IBF
Invertible bloom filter.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static int prepare_ibf(struct Operation *op, uint32_t size)
Create an ibf with the operation&#39;s elements of the specified size.
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
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:

◆ get_order_from_difference()

static unsigned int get_order_from_difference ( unsigned int  diff)
static

Compute the necessary order of an ibf from the size of the symmetric set difference.

Parameters
diffthe difference
Returns
the required size of the ibf

Definition at line 1247 of file gnunet-service-setu.c.

References IBF_ALPHA, MAX_IBF_ORDER, and SE_IBF_HASH_NUM.

Referenced by handle_union_p2p_strata_estimator().

1248 {
1249  unsigned int ibf_order;
1250 
1251  ibf_order = 2;
1252  while (((1 << ibf_order) < (IBF_ALPHA * diff) ||
1253  ((1 << ibf_order) < SE_IBF_HASH_NUM)) &&
1254  (ibf_order < MAX_IBF_ORDER))
1255  ibf_order++;
1256  // add one for correction
1257  return ibf_order + 1;
1258 }
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
#define IBF_ALPHA
Number of buckets used in the ibf per estimated difference.
#define MAX_IBF_ORDER
The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).
Here is the caller graph for this function:

◆ send_full_element_iterator()

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

Send a set element.

Parameters
clsthe union operation struct Operation *
keyunused
valuethe struct ElementEntry * to insert into the key-to-element mapping
Returns
GNUNET_YES (to continue iterating)

Definition at line 1271 of file gnunet-service-setu.c.

References GNUNET_SETU_Element::data, el, ElementEntry::element, GNUNET_SETU_Element::element_type, GNUNET_SETU_ElementMessage::element_type, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_YES, LOG, Operation::mq, GNUNET_SETU_Element::size, and value.

Referenced by send_full_set().

1274 {
1275  struct Operation *op = cls;
1276  struct GNUNET_SETU_ElementMessage *emsg;
1277  struct ElementEntry *ee = value;
1278  struct GNUNET_SETU_Element *el = &ee->element;
1279  struct GNUNET_MQ_Envelope *ev;
1280 
1282  "Sending element %s\n",
1283  GNUNET_h2s (key));
1284  ev = GNUNET_MQ_msg_extra (emsg,
1285  el->size,
1287  emsg->element_type = htons (el->element_type);
1288  GNUNET_memcpy (&emsg[1],
1289  el->data,
1290  el->size);
1291  GNUNET_MQ_send (op->mq,
1292  ev);
1293  return GNUNET_YES;
1294 }
const void * data
Actual data 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).
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
#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
static char * value
Value of the record to add/remove.
Information about an element element in the set.
uint16_t element_type
Application-specific element type.
#define LOG(kind,...)
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
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
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
Definition: gnunet-abd.c:51
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Element stored in a set.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_full_set()

static void send_full_set ( struct Operation op)
static

Switch to full set transmission for op.

Parameters
opoperation to switch to full set transmission.

Definition at line 1303 of file gnunet-service-setu.c.

References Set::content, SetContent::elements, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), LOG, Operation::mq, Operation::phase, PHASE_FULL_SENDING, send_full_element_iterator(), and Operation::set.

Referenced by handle_union_p2p_request_full(), and handle_union_p2p_strata_estimator().

1304 {
1305  struct GNUNET_MQ_Envelope *ev;
1306 
1307  op->phase = PHASE_FULL_SENDING;
1309  "Dedicing to transmit the full set\n");
1310  /* FIXME: use a more memory-friendly way of doing this with an
1311  iterator, just as we do in the non-full case! */
1314  op);
1316  GNUNET_MQ_send (op->mq,
1317  ev);
1318 }
After sending the full set, wait for responses with the elements that the local peer is missing...
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
static int send_full_element_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Send a set element.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
#define LOG(kind,...)
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
struct SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
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
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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:

◆ check_union_p2p_strata_estimator()

static int check_union_p2p_strata_estimator ( void *  cls,
const struct StrataEstimatorMessage msg 
)
static

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 1328 of file gnunet-service-setu.c.

References GNUNET_break, GNUNET_MESSAGE_TYPE_SETU_P2P_SEC, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, StrataEstimatorMessage::header, IBF_BUCKET_SIZE, len, Operation::phase, PHASE_EXPECT_SE, SE_IBF_SIZE, SE_STRATA_COUNT, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

1330 {
1331  struct Operation *op = cls;
1332  int is_compressed;
1333  size_t len;
1334 
1335  if (op->phase != PHASE_EXPECT_SE)
1336  {
1337  GNUNET_break (0);
1338  return GNUNET_SYSERR;
1339  }
1340  is_compressed = (GNUNET_MESSAGE_TYPE_SETU_P2P_SEC == htons (
1341  msg->header.type));
1342  len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
1343  if ((GNUNET_NO == is_compressed) &&
1345  {
1346  GNUNET_break (0);
1347  return GNUNET_SYSERR;
1348  }
1349  return GNUNET_OK;
1350 }
enum IntersectionOperationPhase phase
Current state of the operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEC
Compressed strata estimator.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
Strata estimator together with the peer&#39;s overall set size.
Operation context used to execute a set operation.
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
We sent the request message, and expect a strata estimator.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...

◆ handle_union_p2p_strata_estimator()

static void handle_union_p2p_strata_estimator ( void *  cls,
const struct StrataEstimatorMessage msg 
)
static

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 1360 of file gnunet-service-setu.c.

References Operation::byzantine, Operation::channel, removetrailingwhitespace::f, fail_union_operation(), Operation::force_full, get_order_from_difference(), getenv(), GNUNET_assert, GNUNET_break, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL, GNUNET_MESSAGE_TYPE_SETU_P2P_SEC, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, GNUNET_ntohll(), GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, StrataEstimatorMessage::header, Operation::initial_size, len, LOG, Operation::mq, Operation::phase, PHASE_FULL_RECEIVING, Operation::se, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, send_full_set(), send_ibf(), StrataEstimatorMessage::set_size, GNUNET_MessageHeader::size, strata_estimator_create(), strata_estimator_destroy(), strata_estimator_difference(), strata_estimator_read(), and GNUNET_MessageHeader::type.

1362 {
1363  struct Operation *op = cls;
1364  struct StrataEstimator *remote_se;
1365  unsigned int diff;
1366  uint64_t other_size;
1367  size_t len;
1368  int is_compressed;
1369 
1370  is_compressed = (GNUNET_MESSAGE_TYPE_SETU_P2P_SEC == htons (
1371  msg->header.type));
1373  "# bytes of SE received",
1374  ntohs (msg->header.size),
1375  GNUNET_NO);
1376  len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
1377  other_size = GNUNET_ntohll (msg->set_size);
1379  SE_IBF_SIZE,
1380  SE_IBF_HASH_NUM);
1381  if (NULL == remote_se)
1382  {
1383  /* insufficient resources, fail */
1384  fail_union_operation (op);
1385  return;
1386  }
1387  if (GNUNET_OK !=
1388  strata_estimator_read (&msg[1],
1389  len,
1390  is_compressed,
1391  remote_se))
1392  {
1393  /* decompression failed */
1394  strata_estimator_destroy (remote_se);
1395  fail_union_operation (op);
1396  return;
1397  }
1398  GNUNET_assert (NULL != op->se);
1399  diff = strata_estimator_difference (remote_se,
1400  op->se);
1401 
1402  if (diff > 200)
1403  diff = diff * 3 / 2;
1404 
1405  strata_estimator_destroy (remote_se);
1407  op->se = NULL;
1409  "got se diff=%d, using ibf size %d\n",
1410  diff,
1411  1U << get_order_from_difference (diff));
1412 
1413  {
1414  char *set_debug;
1415 
1416  set_debug = getenv ("GNUNET_SETU_BENCHMARK");
1417  if ((NULL != set_debug) &&
1418  (0 == strcmp (set_debug, "1")))
1419  {
1420  FILE *f = fopen ("set.log", "a");
1421  fprintf (f, "%llu\n", (unsigned long long) diff);
1422  fclose (f);
1423  }
1424  }
1425 
1426  if ((GNUNET_YES == op->byzantine) &&
1427  (other_size < op->byzantine_lower_bound))
1428  {
1429  GNUNET_break (0);
1430  fail_union_operation (op);
1431  return;
1432  }
1433 
1434  if ((GNUNET_YES == op->force_full) ||
1435  (diff > op->initial_size / 4) ||
1436  (0 == other_size))
1437  {
1439  "Deciding to go for full set transmission (diff=%d, own set=%llu)\n",
1440  diff,
1441  (unsigned long long) op->initial_size);
1443  "# of full sends",
1444  1,
1445  GNUNET_NO);
1446  if ((op->initial_size <= other_size) ||
1447  (0 == other_size))
1448  {
1449  send_full_set (op);
1450  }
1451  else
1452  {
1453  struct GNUNET_MQ_Envelope *ev;
1454 
1456  "Telling other peer that we expect its full set\n");
1458  ev = GNUNET_MQ_msg_header (
1460  GNUNET_MQ_send (op->mq,
1461  ev);
1462  }
1463  }
1464  else
1465  {
1467  "# of ibf sends",
1468  1,
1469  GNUNET_NO);
1470  if (GNUNET_OK !=
1471  send_ibf (op,
1472  get_order_from_difference (diff)))
1473  {
1474  /* Internal error, best we can do is shut the connection */
1476  "Failed to send IBF, closing connection\n");
1477  fail_union_operation (op);
1478  return;
1479  }
1480  }
1482 }
struct StrataEstimator * se
Copy of the set&#39;s strata estimator at the time of creation of this operation.
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
enum IntersectionOperationPhase phase
Current state of the operation.
struct StrataEstimator * strata_estimator_create(unsigned int strata_count, uint32_t ibf_size, uint8_t ibf_hashnum)
Create a new strata estimator with the given parameters.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C)
uint64_t initial_size
Initial size of our set, just before the operation started.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A handle to a strata estimator.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEC
Compressed strata estimator.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
#define LOG(kind,...)
int strata_estimator_read(const void *buf, size_t buf_len, int is_compressed, struct StrataEstimator *se)
Read strata from the buffer into the given strata estimator.
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
char * getenv()
Strata estimator together with the peer&#39;s overall set size.
unsigned int strata_estimator_difference(const struct StrataEstimator *se1, const struct StrataEstimator *se2)
Estimate set difference with two strata estimators, i.e.
Operation context used to execute a set operation.
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
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,...)
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
Phase that receives full set first and then sends elements that are the local peer missing...
static unsigned int get_order_from_difference(unsigned int diff)
Compute the necessary order of an ibf from the size of the symmetric set difference.
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
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
int force_full
Always send full sets, even if delta operations would be more efficient.
Here is the call graph for this function:

◆ send_offers_iterator()

static int send_offers_iterator ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator to send elements to a remote peer.

Parameters
clsclosure with the element key and the union operation
keyignored
valuethe key entry

Definition at line 1493 of file gnunet-service-setu.c.

References KeyEntry::element, ElementEntry::element_hash, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), GNUNET_YES, KeyEntry::ibf_key, SendElementClosure::ibf_key, IBF_Key::key_val, LOG, mh, Operation::mq, SendElementClosure::op, and value.

Referenced by send_offers_for_key().

1496 {
1497  struct SendElementClosure *sec = cls;
1498  struct Operation *op = sec->op;
1499  struct KeyEntry *ke = value;
1500  struct GNUNET_MQ_Envelope *ev;
1501  struct GNUNET_MessageHeader *mh;
1502 
1503  /* Detect 32-bit key collision for the 64-bit IBF keys. */
1504  if (ke->ibf_key.key_val != sec->ibf_key.key_val)
1505  return GNUNET_YES;
1506 
1507  ev = GNUNET_MQ_msg_header_extra (mh,
1508  sizeof(struct GNUNET_HashCode),
1510 
1511  GNUNET_assert (NULL != ev);
1512  *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash;
1514  "[OP %p] sending element offer (%s) to peer\n",
1515  op,
1516  GNUNET_h2s (&ke->element->element_hash));
1517  GNUNET_MQ_send (op->mq, ev);
1518  return GNUNET_YES;
1519 }
struct Operation * op
Operation for which the elements should be sent.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
#define GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER
Tell the other peer which hashes match a given IBF key.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint64_t key_val
Definition: ibf.h:47
The key entry is used to associate an ibf key with an element.
static char * value
Value of the record to add/remove.
struct IBF_Key ibf_key
IBF key for the entry, derived from the current salt.
struct ElementEntry * element
The actual element associated with the key.
A 512-bit hashcode.
#define LOG(kind,...)
#define GNUNET_MQ_msg_header_extra(mh, esize, type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space...
Definition: gnunet_mq_lib.h:88
Operation context used to execute a set operation.
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
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Used as a closure for sending elements with a specific IBF key.
struct IBF_Key ibf_key
The IBF key whose matching elements should be sent.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_offers_for_key()

static void send_offers_for_key ( struct Operation op,
struct IBF_Key  ibf_key 
)
static

Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key.

Parameters
opunion operation
ibf_keyIBF key of interest

Definition at line 1529 of file gnunet-service-setu.c.

References GNUNET_CONTAINER_multihashmap32_get_multiple(), SendElementClosure::ibf_key, Operation::key_to_element, op, SendElementClosure::op, and send_offers_iterator().

Referenced by decode_and_send(), and handle_union_p2p_inquiry().

1531 {
1532  struct SendElementClosure send_cls;
1533 
1534  send_cls.ibf_key = ibf_key;
1535  send_cls.op = op;
1537  op->key_to_element,
1538  (uint32_t) ibf_key.
1539  key_val,
1541  &send_cls);
1542 }
int GNUNET_CONTAINER_multihashmap32_get_multiple(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
static int send_offers_iterator(void *cls, uint32_t key, void *value)
Iterator to send elements to a remote peer.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Used as a closure for sending elements with a specific IBF key.
struct IBF_Key ibf_key
The IBF key whose matching elements should be sent.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_and_send()

static int decode_and_send ( struct Operation op)
static

Decode which elements are missing on each side, and send the appropriate offers and inquiries.

Parameters
opunion operation
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 1553 of file gnunet-service-setu.c.

References fail_union_operation(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_DONE, GNUNET_MESSAGE_TYPE_SETU_P2P_INQUIRY, GNUNET_MQ_msg_extra, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, ibf_decode(), ibf_destroy(), ibf_dup(), ibf_subtract(), key, IBF_Key::key_val, Operation::local_ibf, LOG, MAX_IBF_ORDER, Operation::mq, msg, Operation::phase, PHASE_ACTIVE_DECODING, prepare_ibf(), Operation::remote_ibf, res, InquiryMessage::salt, Operation::salt_receive, Operation::salt_send, send_ibf(), send_offers_for_key(), size, InvertibleBloomFilter::size, and unsalt_key().

Referenced by handle_union_p2p_ibf().

1554 {
1555  struct IBF_Key key;
1556  struct IBF_Key last_key;
1557  int side;
1558  unsigned int num_decoded;
1559  struct InvertibleBloomFilter *diff_ibf;
1560 
1562 
1563  if (GNUNET_OK !=
1564  prepare_ibf (op,
1565  op->remote_ibf->size))
1566  {
1567  GNUNET_break (0);
1568  /* allocation failed */
1569  return GNUNET_SYSERR;
1570  }
1571  diff_ibf = ibf_dup (op->local_ibf);
1572  ibf_subtract (diff_ibf,
1573  op->remote_ibf);
1574 
1575  ibf_destroy (op->remote_ibf);
1576  op->remote_ibf = NULL;
1577 
1579  "decoding IBF (size=%u)\n",
1580  diff_ibf->size);
1581 
1582  num_decoded = 0;
1583  key.key_val = 0; /* just to avoid compiler thinking we use undef'ed variable */
1584 
1585  while (1)
1586  {
1587  int res;
1588  int cycle_detected = GNUNET_NO;
1589 
1590  last_key = key;
1591 
1592  res = ibf_decode (diff_ibf,
1593  &side,
1594  &key);
1595  if (res == GNUNET_OK)
1596  {
1598  "decoded ibf key %lx\n",
1599  (unsigned long) key.key_val);
1600  num_decoded += 1;
1601  if ((num_decoded > diff_ibf->size) ||
1602  ((num_decoded > 1) &&
1603  (last_key.key_val == key.key_val)))
1604  {
1606  "detected cyclic ibf (decoded %u/%u)\n",
1607  num_decoded,
1608  diff_ibf->size);
1609  cycle_detected = GNUNET_YES;
1610  }
1611  }
1612  if ((GNUNET_SYSERR == res) ||
1613  (GNUNET_YES == cycle_detected))
1614  {
1615  int next_order;
1616  next_order = 0;
1617  while (1 << next_order < diff_ibf->size)
1618  next_order++;
1619  next_order++;
1620  if (next_order <= MAX_IBF_ORDER)
1621  {
1623  "decoding failed, sending larger ibf (size %u)\n",
1624  1 << next_order);
1626  "# of IBF retries",
1627  1,
1628  GNUNET_NO);
1629  op->salt_send++;
1630  if (GNUNET_OK !=
1631  send_ibf (op, next_order))
1632  {
1633  /* Internal error, best we can do is shut the connection */
1635  "Failed to send IBF, closing connection\n");
1636  fail_union_operation (op);
1637  ibf_destroy (diff_ibf);
1638  return GNUNET_SYSERR;
1639  }
1640  }
1641  else
1642  {
1644  "# of failed union operations (too large)",
1645  1,
1646  GNUNET_NO);
1647  // XXX: Send the whole set, element-by-element
1649  "set union failed: reached ibf limit\n");
1650  fail_union_operation (op);
1651  ibf_destroy (diff_ibf);
1652  return GNUNET_SYSERR;
1653  }
1654  break;
1655  }
1656  if (GNUNET_NO == res)
1657  {
1658  struct GNUNET_MQ_Envelope *ev;
1659 
1661  "transmitted all values, sending DONE\n");
1663  GNUNET_MQ_send (op->mq, ev);
1664  /* We now wait until we get a DONE message back
1665  * and then wait for our MQ to be flushed and all our
1666  * demands be delivered. */
1667  break;
1668  }
1669  if (1 == side)
1670  {
1671  struct IBF_Key unsalted_key;
1672 
1673  unsalt_key (&key,
1674  op->salt_receive,
1675  &unsalted_key);
1676  send_offers_for_key (op,
1677  unsalted_key);
1678  }
1679  else if (-1 == side)
1680  {
1681  struct GNUNET_MQ_Envelope *ev;
1682  struct InquiryMessage *msg;
1683 
1684  /* It may be nice to merge multiple requests, but with CADET's corking it is not worth
1685  * the effort additional complexity. */
1686  ev = GNUNET_MQ_msg_extra (msg,
1687  sizeof(struct IBF_Key),
1689  msg->salt = htonl (op->salt_receive);
1690  GNUNET_memcpy (&msg[1],
1691  &key,
1692  sizeof(struct IBF_Key));
1694  "sending element inquiry for IBF key %lx\n",
1695  (unsigned long) key.key_val);
1696  GNUNET_MQ_send (op->mq, ev);
1697  }
1698  else
1699  {
1700  GNUNET_assert (0);
1701  }
1702  }
1703  ibf_destroy (diff_ibf);
1704  return GNUNET_OK;
1705 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum IntersectionOperationPhase phase
Current state of the operation.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Invertible bloom filter (IBF).
Definition: ibf.h:82
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static void send_offers_for_key(struct Operation *op, struct IBF_Key ibf_key)
Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key.
static void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_DONE
Set operation is done.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct InvertibleBloomFilter * ibf_dup(const struct InvertibleBloomFilter *ibf)
Create a copy of an IBF, the copy has to be destroyed properly.
Definition: ibf.c:379
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
#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
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
int ibf_decode(struct InvertibleBloomFilter *ibf, int *ret_side, struct IBF_Key *ret_id)
Decode and remove an element from the IBF, if possible.
Definition: ibf.c:228
void ibf_subtract(struct InvertibleBloomFilter *ibf1, const struct InvertibleBloomFilter *ibf2)
Subtract ibf2 from ibf1, storing the result in ibf1.
Definition: ibf.c:356
static int res
#define LOG(kind,...)
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void ibf_destroy(struct InvertibleBloomFilter *ibf)
Destroy all resources associated with the invertible bloom filter.
Definition: ibf.c:403
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
We are decoding an IBF.
struct InvertibleBloomFilter * local_ibf
The IBF with the local set&#39;s element.
#define GNUNET_log(kind,...)
#define MAX_IBF_ORDER
The maximum size of an ibf we use is 2^(MAX_IBF_ORDER).
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
static int prepare_ibf(struct Operation *op, uint32_t size)
Create an ibf with the operation&#39;s elements of the specified size.
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
uint32_t salt
Salt used when hashing elements for this inquiry.
uint32_t salt_send
Salt that we&#39;re using for sending IBFs.
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_INQUIRY
Tell the other peer to send us a list of hashes that match an IBF key.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_union_p2p_ibf()

static int check_union_p2p_ibf ( void *  cls,
const struct IBFMessage msg 
)
static

Check an IBF message from a remote peer.

Reassemble the IBF from multiple pieces, and process the whole IBF once possible.

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

Definition at line 1719 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, IBFMessage::header, IBF_BUCKET_SIZE, Operation::ibf_buckets_received, msg, IBFMessage::offset, IBFMessage::order, Operation::phase, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_LAST, PHASE_PASSIVE_DECODING, Operation::remote_ibf, IBFMessage::salt, Operation::salt_receive, InvertibleBloomFilter::size, and GNUNET_MessageHeader::size.

1721 {
1722  struct Operation *op = cls;
1723  unsigned int buckets_in_message;
1724 
1725  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1726  / IBF_BUCKET_SIZE;
1727  if (0 == buckets_in_message)
1728  {
1729  GNUNET_break_op (0);
1730  return GNUNET_SYSERR;
1731  }
1732  if ((ntohs (msg->header.size) - sizeof *msg) != buckets_in_message
1733  * IBF_BUCKET_SIZE)
1734  {
1735  GNUNET_break_op (0);
1736  return GNUNET_SYSERR;
1737  }
1738  if (op->phase == PHASE_EXPECT_IBF_LAST)
1739  {
1740  if (ntohl (msg->offset) != op->ibf_buckets_received)
1741  {
1742  GNUNET_break_op (0);
1743  return GNUNET_SYSERR;
1744  }
1745  if (1 << msg->order != op->remote_ibf->size)
1746  {
1747  GNUNET_break_op (0);
1748  return GNUNET_SYSERR;
1749  }
1750  if (ntohl (msg->salt) != op->salt_receive)
1751  {
1752  GNUNET_break_op (0);
1753  return GNUNET_SYSERR;
1754  }
1755  }
1756  else if ((op->phase != PHASE_PASSIVE_DECODING) &&
1757  (op->phase != PHASE_EXPECT_IBF))
1758  {
1759  GNUNET_break_op (0);
1760  return GNUNET_SYSERR;
1761  }
1762 
1763  return GNUNET_OK;
1764 }
uint32_t offset
Offset of the strata in the rest of the message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum IntersectionOperationPhase phase
Current state of the operation.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
The other peer is decoding the IBF we just sent.
unsigned int ibf_buckets_received
Number of ibf buckets already received into the remote_ibf.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
We sent the strata estimator, and expect an IBF.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
Continuation for multi part IBFs.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
Operation context used to execute a set operation.
uint32_t salt
Salt used when hashing elements for this IBF.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_ibf()

static void handle_union_p2p_ibf ( void *  cls,
const struct IBFMessage msg 
)
static

Handle an IBF message from a remote peer.

Reassemble the IBF from multiple pieces, and process the whole IBF once possible.

Parameters
clsthe union operation
msgthe header of the message

Definition at line 1777 of file gnunet-service-setu.c.

References Operation::channel, decode_and_send(), fail_union_operation(), GNUNET_assert, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, IBFMessage::header, IBF_BUCKET_SIZE, Operation::ibf_buckets_received, ibf_create(), ibf_read_slice(), LOG, msg, IBFMessage::offset, IBFMessage::order, Operation::phase, PHASE_ACTIVE_DECODING, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_LAST, PHASE_PASSIVE_DECODING, Operation::remote_ibf, IBFMessage::salt, Operation::salt_receive, SE_IBF_HASH_NUM, InvertibleBloomFilter::size, and GNUNET_MessageHeader::size.

1779 {
1780  struct Operation *op = cls;
1781  unsigned int buckets_in_message;
1782 
1783  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1784  / IBF_BUCKET_SIZE;
1785  if ((op->phase == PHASE_PASSIVE_DECODING) ||
1786  (op->phase == PHASE_EXPECT_IBF))
1787  {
1789  GNUNET_assert (NULL == op->remote_ibf);
1791  "Creating new ibf of size %u\n",
1792  1 << msg->order);
1793  op->remote_ibf = ibf_create (1 << msg->order, SE_IBF_HASH_NUM);
1794  op->salt_receive = ntohl (msg->salt);
1796  "Receiving new IBF with salt %u\n",
1797  op->salt_receive);
1798  if (NULL == op->remote_ibf)
1799  {
1801  "Failed to parse remote IBF, closing connection\n");
1802  fail_union_operation (op);
1803  return;
1804  }
1805  op->ibf_buckets_received = 0;
1806  if (0 != ntohl (msg->offset))
1807  {
1808  GNUNET_break_op (0);
1809  fail_union_operation (op);
1810  return;
1811  }
1812  }
1813  else
1814  {
1817  "Received more of IBF\n");
1818  }
1819  GNUNET_assert (NULL != op->remote_ibf);
1820 
1821  ibf_read_slice (&msg[1],
1823  buckets_in_message,
1824  op->remote_ibf);
1825  op->ibf_buckets_received += buckets_in_message;
1826 
1827  if (op->ibf_buckets_received == op->remote_ibf->size)
1828  {
1830  "received full ibf\n");
1832  if (GNUNET_OK !=
1833  decode_and_send (op))
1834  {
1835  /* Internal error, best we can do is shut down */
1837  "Failed to decode IBF, closing connection\n");
1838  fail_union_operation (op);
1839  return;
1840  }
1841  }
1843 }
uint32_t offset
Offset of the strata in the rest of the message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
enum IntersectionOperationPhase phase
Current state of the operation.
struct InvertibleBloomFilter * remote_ibf
The IBF we currently receive.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
The other peer is decoding the IBF we just sent.
unsigned int ibf_buckets_received
Number of ibf buckets already received into the remote_ibf.
uint32_t salt_receive
Salt for the IBF we&#39;ve received and that we&#39;re currently decoding.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t size
How many cells does this IBF have?
Definition: ibf.h:87
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint8_t order
Order of the whole ibf, where num_buckets = 2^order.
We sent the strata estimator, and expect an IBF.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
Continuation for multi part IBFs.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
#define LOG(kind,...)
void ibf_read_slice(const void *buf, uint32_t start, uint32_t count, struct InvertibleBloomFilter *ibf)
Read buckets from a buffer into an ibf.
Definition: ibf.c:323
static int decode_and_send(struct Operation *op)
Decode which elements are missing on each side, and send the appropriate offers and inquiries...
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:79
Operation context used to execute a set operation.
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.
We are decoding an IBF.
uint32_t salt
Salt used when hashing elements for this IBF.
#define GNUNET_log(kind,...)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ send_client_element()

static void send_client_element ( struct Operation op,
const struct GNUNET_SETU_Element element,
enum GNUNET_SETU_Status  status 
)
static

Send a result message to the client indicating that there is a new element.

Parameters
opunion operation
elementelement to send
statusstatus to send with the new element

Definition at line 1855 of file gnunet-service-setu.c.

References Operation::client_request_id, Set::cs, GNUNET_SETU_ResultMessage::current_size, GNUNET_SETU_Element::data, GNUNET_SETU_Element::element_type, GNUNET_SETU_ResultMessage::element_type, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap32_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_htonll(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_RESULT, GNUNET_MQ_discard(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), Operation::key_to_element, LOG, ClientState::mq, GNUNET_SETU_ResultMessage::request_id, GNUNET_SETU_ResultMessage::result_status, Operation::set, and GNUNET_SETU_Element::size.

Referenced by handle_union_p2p_demand(), handle_union_p2p_elements(), and handle_union_p2p_full_element().

1858 {
1859  struct GNUNET_MQ_Envelope *ev;
1860  struct GNUNET_SETU_ResultMessage *rm;
1861 
1863  "sending element (size %u) to client\n",
1864  element->size);
1865  GNUNET_assert (0 != op->client_request_id);
1866  ev = GNUNET_MQ_msg_extra (rm,
1867  element->size,
1869  if (NULL == ev)
1870  {
1871  GNUNET_MQ_discard (ev);
1872  GNUNET_break (0);
1873  return;
1874  }
1875  rm->result_status = htons (status);
1876  rm->request_id = htonl (op->client_request_id);
1877  rm->element_type = htons (element->element_type);
1879  op->key_to_element));
1880  GNUNET_memcpy (&rm[1],
1881  element->data,
1882  element->size);
1883  GNUNET_MQ_send (op->set->cs->mq,
1884  ev);
1885 }
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
const void * data
Actual data 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.
uint32_t request_id
id the result belongs to
Definition: setu.h:254
uint16_t element_type
Type of the element attachted to the message, if any.
Definition: setu.h:265
#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
#define GNUNET_MESSAGE_TYPE_SETU_RESULT
Handle result message from operation.
uint16_t element_type
Application-specific element type.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
uint16_t status
See PRISM_STATUS_*-constants.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
uint16_t result_status
Was the evaluation successful? Contains an enum GNUNET_SETU_Status in NBO.
Definition: setu.h:260
#define LOG(kind,...)
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:323
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
uint64_t current_size
Current set size.
Definition: setu.h:249
struct ClientState * cs
Client that owns the set.
Message sent by the service to the client to indicate an element that is removed (set intersection) o...
Definition: setu.h:239
uint32_t client_request_id
ID used to identify an operation between service and client.
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
uint16_t size
Number of bytes in the buffer pointed to by data.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ maybe_finish()

static void maybe_finish ( struct Operation op)
static

Tests if the operation is finished, and if so notify.

Parameters
opoperation to check

Definition at line 1894 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), Operation::demanded_hashes, GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_SETU_P2P_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), LOG, Operation::mq, Operation::phase, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, PHASE_FINISHED, and send_client_done().

Referenced by handle_union_p2p_done(), and handle_union_p2p_elements().

1895 {
1896  unsigned int num_demanded;
1897 
1898  num_demanded = GNUNET_CONTAINER_multihashmap_size (
1899  op->demanded_hashes);
1900 
1901  if (PHASE_FINISH_WAITING == op->phase)
1902  {
1904  "In PHASE_FINISH_WAITING, pending %u demands\n",
1905  num_demanded);
1906  if (0 == num_demanded)
1907  {
1908  struct GNUNET_MQ_Envelope *ev;
1909 
1910  op->phase = PHASE_FINISHED;
1912  GNUNET_MQ_send (op->mq,
1913  ev);
1914  /* We now wait until the other peer sends P2P_OVER
1915  * after it got all elements from us. */
1916  }
1917  }
1918  if (PHASE_FINISH_CLOSING == op->phase)
1919  {
1921  "In PHASE_FINISH_CLOSING, pending %u demands\n",
1922  num_demanded);
1923  if (0 == num_demanded)
1924  {
1925  op->phase = PHASE_FINISHED;
1926  send_client_done (op);
1928  }
1929  }
1930 }
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.
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
#define GNUNET_MESSAGE_TYPE_SETU_P2P_DONE
Set operation is done.
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...
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
In the penultimate phase, we wait until all our demands are satisfied.
#define LOG(kind,...)
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
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:

◆ check_union_p2p_elements()

static int check_union_p2p_elements ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Check an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1940 of file gnunet-service-setu.c.

References Operation::demanded_hashes, GNUNET_break_op, GNUNET_CONTAINER_multihashmap_size(), GNUNET_OK, and GNUNET_SYSERR.

1942 {
1943  struct Operation *op = cls;
1944 
1946  {
1947  GNUNET_break_op (0);
1948  return GNUNET_SYSERR;
1949  }
1950  return GNUNET_OK;
1951 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ handle_union_p2p_elements()

static void handle_union_p2p_elements ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Handle an element message from a remote peer.

Sent by the other peer either because we decoded an IBF and placed a demand, or because the other peer switched to full set transmission.

Parameters
clsthe union operation
emsgthe message

Definition at line 1963 of file gnunet-service-setu.c.

References Operation::channel, GNUNET_SET_Element::data, Operation::demanded_hashes, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_SETU_element_hash(), GNUNET_SETU_STATUS_ADD_LOCAL, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SETU_ElementMessage::header, LOG, maybe_finish(), op_get_element(), op_register_element(), KeyEntry::received, Operation::received_fresh, Operation::received_total, ElementEntry::remote, send_client_element(), GNUNET_SET_Element::size, and GNUNET_MessageHeader::size.

1965 {
1966  struct Operation *op = cls;
1967  struct ElementEntry *ee;
1968  struct KeyEntry *ke;
1969  uint16_t element_size;
1970 
1971  element_size = ntohs (emsg->header.size) - sizeof(struct
1973  ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
1974  GNUNET_memcpy (&ee[1],
1975  &emsg[1],
1976  element_size);
1977  ee->element.size = element_size;
1978  ee->element.data = &ee[1];
1979  ee->element.element_type = ntohs (emsg->element_type);
1980  ee->remote = GNUNET_YES;
1982  &ee->element_hash);
1983  if (GNUNET_NO ==
1985  &ee->element_hash,
1986  NULL))
1987  {
1988  /* We got something we didn't demand, since it's not in our map. */
1989  GNUNET_break_op (0);
1990  fail_union_operation (op);
1991  return;
1992  }
1993 
1995  "Got element (size %u, hash %s) from peer\n",
1996  (unsigned int) element_size,
1997  GNUNET_h2s (&ee->element_hash));
1998 
2000  "# received elements",
2001  1,
2002  GNUNET_NO);
2004  "# exchanged elements",
2005  1,
2006  GNUNET_NO);
2007 
2008  op->received_total++;
2009 
2010  ke = op_get_element (op,
2011  &ee->element_hash);
2012  if (NULL != ke)
2013  {
2014  /* Got repeated element. Should not happen since
2015  * we track demands. */
2017  "# repeated elements",
2018  1,
2019  GNUNET_NO);
2020  ke->received = GNUNET_YES;
2021  GNUNET_free (ee);
2022  }
2023  else
2024  {
2026  "Registering new element from remote peer\n");
2027  op->received_fresh++;
2028  op_register_element (op, ee, GNUNET_YES);
2029  /* only send results immediately if the client wants it */
2030  send_client_element (op,
2031  &ee->element,
2033  }
2034 
2035  if ((op->received_total > 8) &&
2036  (op->received_fresh < op->received_total / 3))
2037  {
2038  /* The other peer gave us lots of old elements, there's something wrong. */
2039  GNUNET_break_op (0);
2040  fail_union_operation (op);
2041  return;
2042  }
2044  maybe_finish (op);
2045 }
uint32_t received_fresh
Number of elements we received from the other peer that were not in the local set yet...
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
static unsigned int element_size
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
static void send_client_element(struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
Send a result message to the client indicating that there is a new element.
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).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
static struct KeyEntry * op_get_element(struct Operation *op, const struct GNUNET_HashCode *element_hash)
Determine whether the given element is already in the operation&#39;s element set.
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
Element should be added to the result set of the local peer, i.e.
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.
void GNUNET_SETU_element_hash(const struct GNUNET_SETU_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: setu_api.c:876
#define LOG(kind,...)
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
static void op_register_element(struct Operation *op, struct ElementEntry *ee, int received)
Insert an element into the union operation&#39;s key-to-element mapping.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
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.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETU_ADD.
Definition: setu.h:280
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
#define GNUNET_malloc(size)
Wrapper around malloc.
uint32_t received_total
Total number of elements received from the other peer.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:

◆ check_union_p2p_full_element()

static int check_union_p2p_full_element ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Check a full element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 2055 of file gnunet-service-setu.c.

References GNUNET_OK.

2057 {
2058  struct Operation *op = cls;
2059 
2060  (void) op;
2061 
2062  // FIXME: check that we expect full elements here?
2063  return GNUNET_OK;
2064 }
Operation context used to execute a set operation.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_full_element()

static void handle_union_p2p_full_element ( void *  cls,
const struct GNUNET_SETU_ElementMessage emsg 
)
static

Handle an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 2074 of file gnunet-service-setu.c.

References Operation::byzantine, Operation::channel, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_SETU_element_hash(), GNUNET_SETU_STATUS_ADD_LOCAL, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SETU_ElementMessage::header, LOG, op_get_element(), op_register_element(), Operation::phase, PHASE_EXPECT_IBF, PHASE_FULL_RECEIVING, KeyEntry::received, Operation::received_fresh, Operation::received_total, ElementEntry::remote, send_client_element(), GNUNET_SET_Element::size, and GNUNET_MessageHeader::size.

2076 {
2077  struct Operation *op = cls;
2078  struct ElementEntry *ee;
2079  struct KeyEntry *ke;
2080  uint16_t element_size;
2081 
2082 
2083  /* Allow only receiving of full element message if in expect IBF or in PHASE_FULL_RECEIVING state */
2084  if ( (PHASE_EXPECT_IBF != op->phase) &&
2085  (PHASE_FULL_RECEIVING != op->phase) )
2086  {
2087  GNUNET_break_op (0);
2088  fail_union_operation (op);
2089  return;
2090  }
2091 
2093 
2094  element_size = ntohs (emsg->header.size)
2095  - sizeof(struct GNUNET_SETU_ElementMessage);
2096  ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
2097  GNUNET_memcpy (&ee[1], &emsg[1], element_size);
2098  ee->element.size = element_size;
2099  ee->element.data = &ee[1];
2100  ee->element.element_type = ntohs (emsg->element_type);
2101  ee->remote = GNUNET_YES;
2103  &ee->element_hash);
2105  "Got element (full diff, size %u, hash %s) from peer\n",
2106  (unsigned int) element_size,
2107  GNUNET_h2s (&ee->element_hash));
2108 
2110  "# received elements",
2111  1,
2112  GNUNET_NO);
2114  "# exchanged elements",
2115  1,
2116  GNUNET_NO);
2117 
2118  op->received_total++;
2119 
2120  ke = op_get_element (op,
2121  &ee->element_hash);
2122  if (NULL != ke)
2123  {
2124  /* Got repeated element. Should not happen since
2125  * we track demands. */
2127  "# repeated elements",
2128  1,
2129  GNUNET_NO);
2130  ke->received = GNUNET_YES;
2131  GNUNET_free (ee);
2132  }
2133  else
2134  {
2136  "Registering new element from remote peer\n");
2137  op->received_fresh++;
2138  op_register_element (op, ee, GNUNET_YES);
2139  /* only send results immediately if the client wants it */
2140  send_client_element (op,
2141  &ee->element,
2143  }
2144 
2145  if ((GNUNET_YES == op->byzantine) &&
2146  (op->received_total > 384 + op->received_fresh * 4) &&
2147  (op->received_fresh < op->received_total / 6))
2148  {
2149  /* The other peer gave us lots of old elements, there's something wrong. */
2151  "Other peer sent only %llu/%llu fresh elements, failing operation\n",
2152  (unsigned long long) op->received_fresh,
2153  (unsigned long long) op->received_total);
2154  GNUNET_break_op (0);
2155  fail_union_operation (op);
2156  return;
2157  }
2159 }
uint32_t received_fresh
Number of elements we received from the other peer that were not in the local set yet...
enum IntersectionOperationPhase phase
Current state of the operation.
static unsigned int element_size
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
static void send_client_element(struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
Send a result message to the client indicating that there is a new element.
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).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
static struct KeyEntry * op_get_element(struct Operation *op, const struct GNUNET_HashCode *element_hash)
Determine whether the given element is already in the operation&#39;s element set.
Information about an element element in the set.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
int remote
GNUNET_YES if the element is a remote element, and does not belong to the operation&#39;s set...
Element should be added to the result set of the local peer, i.e.
We sent the strata estimator, and expect an IBF.
void GNUNET_SETU_element_hash(const struct GNUNET_SETU_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: setu_api.c:876
#define LOG(kind,...)
int byzantine
GNUNET_YES to fail operations where Byzantine faults are suspected
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
static void op_register_element(struct Operation *op, struct ElementEntry *ee, int received)
Insert an element into the union operation&#39;s key-to-element mapping.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
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.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
Phase that receives full set first and then sends elements that are the local peer missing...
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SETU_ADD.
Definition: setu.h:280
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
#define GNUNET_malloc(size)
Wrapper around malloc.
uint32_t received_total
Total number of elements received from the other peer.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:

◆ check_union_p2p_inquiry()

static int check_union_p2p_inquiry ( void *  cls,
const struct InquiryMessage msg 
)
static

Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s).

Parameters
clsthe union operation
msgthe message

Definition at line 2170 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, InquiryMessage::header, Operation::phase, PHASE_PASSIVE_DECODING, and GNUNET_MessageHeader::size.

2172 {
2173  struct Operation *op = cls;
2174  unsigned int num_keys;
2175 
2176  if (op->phase != PHASE_PASSIVE_DECODING)
2177  {
2178  GNUNET_break_op (0);
2179  return GNUNET_SYSERR;
2180  }
2181  num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2182  / sizeof(struct IBF_Key);
2183  if ((ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2184  != num_keys * sizeof(struct IBF_Key))
2185  {
2186  GNUNET_break_op (0);
2187  return GNUNET_SYSERR;
2188  }
2189  return GNUNET_OK;
2190 }
enum IntersectionOperationPhase phase
Current state of the operation.
The other peer is decoding the IBF we just sent.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Operation context used to execute a set operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45

◆ handle_union_p2p_inquiry()

static void handle_union_p2p_inquiry ( void *  cls,
const struct InquiryMessage msg 
)
static

Send offers (for GNUNET_Hash-es) in response to inquiries (for IBF_Key-s).

Parameters
clsthe union operation
msgthe message

Definition at line 2200 of file gnunet-service-setu.c.

References Operation::channel, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, InquiryMessage::header, LOG, InquiryMessage::salt, send_offers_for_key(), GNUNET_MessageHeader::size, and unsalt_key().

2202 {
2203  struct Operation *op = cls;
2204  const struct IBF_Key *ibf_key;
2205  unsigned int num_keys;
2206 
2208  "Received union inquiry\n");
2209  num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
2210  / sizeof(struct IBF_Key);
2211  ibf_key = (const struct IBF_Key *) &msg[1];
2212  while (0 != num_keys--)
2213  {
2214  struct IBF_Key unsalted_key;
2215 
2216  unsalt_key (ibf_key,
2217  ntohl (msg->salt),
2218  &unsalted_key);
2219  send_offers_for_key (op,
2220  unsalted_key);
2221  ibf_key++;
2222  }
2224 }
static void send_offers_for_key(struct Operation *op, struct IBF_Key ibf_key)
Send offers (in the form of GNUNET_Hash-es) to the remote peer for the given IBF key.
static void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define LOG(kind,...)
Operation context used to execute a set operation.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
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 struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:45
uint32_t salt
Salt used when hashing elements for this inquiry.
Here is the call graph for this function:

◆ send_missing_full_elements_iter()

static int send_missing_full_elements_iter ( void *  cls,
uint32_t  key,
void *  value 
)
static

Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries.

Parameters
clsclosure
keycurrent key code
valuevalue in the hash map
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 2238 of file gnunet-service-setu.c.

References GNUNET_SET_Element::data, ElementEntry::element, KeyEntry::element, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_YES, Operation::mq, KeyEntry::received, GNUNET_SET_Element::size, and value.

Referenced by handle_union_p2p_full_done().

2241 {
2242  struct Operation *op = cls;
2243  struct KeyEntry *ke = value;
2244  struct GNUNET_MQ_Envelope *ev;
2245  struct GNUNET_SETU_ElementMessage *emsg;
2246  struct ElementEntry *ee = ke->element;
2247 
2248  if (GNUNET_YES == ke->received)
2249  return GNUNET_YES;
2250  ev = GNUNET_MQ_msg_extra (emsg,
2251  ee->element.size,
2253  GNUNET_memcpy (&emsg[1],
2254  ee->element.data,
2255  ee->element.size);
2256  emsg->element_type = htons (ee->element.element_type);
2257  GNUNET_MQ_send (op->mq,
2258  ev);
2259  return GNUNET_YES;
2260 }
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const void * data
Actual data of the element.
The key entry is used to associate an ibf key with an element.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
#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
static char * value
Value of the record to add/remove.
Information about an element element in the set.
struct ElementEntry * element
The actual element associated with the key.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT
Send a set element, not as response to a demand but because we&#39;re sending the full set...
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
uint16_t size
Number of bytes in the buffer pointed to by data.
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
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_union_p2p_request_full()

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

Handle a request for full set transmission.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 2270 of file gnunet-service-setu.c.

References Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, LOG, Operation::phase, PHASE_EXPECT_IBF, and send_full_set().

2272 {
2273  struct Operation *op = cls;
2274 
2276  "Received request for full set transmission\n");
2277  if (PHASE_EXPECT_IBF != op->phase)
2278  {
2279  GNUNET_break_op (0);
2280  fail_union_operation (op);
2281  return;
2282  }
2283 
2284  // FIXME: we need to check that our set is larger than the
2285  // byzantine_lower_bound by some threshold
2286  send_full_set (op);
2288 }
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
enum IntersectionOperationPhase phase
Current state of the operation.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We sent the strata estimator, and expect an IBF.
#define LOG(kind,...)
Operation context used to execute a set operation.
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 struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ handle_union_p2p_full_done()

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

Handle a "full done" message.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 2298 of file gnunet-service-setu.c.

References _GSS_operation_destroy2(), Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), Operation::key_to_element, LOG, Operation::mq, Operation::phase, PHASE_EXPECT_IBF, PHASE_FINISHED, PHASE_FULL_SENDING, send_client_done(), and send_missing_full_elements_iter().

2300 {
2301  struct Operation *op = cls;
2302 
2303  switch (op->phase)
2304  {
2305  case PHASE_EXPECT_IBF:
2306  {
2307  struct GNUNET_MQ_Envelope *ev;
2308 
2310  "got FULL DONE, sending elements that other peer is missing\n");
2311 
2312  /* send all the elements that did not come from the remote peer */
2315  op);
2317  GNUNET_MQ_send (op->mq,
2318  ev);
2319  op->phase = PHASE_FINISHED;
2320  /* we now wait until the other peer sends us the OVER message*/
2321  }
2322  break;
2323 
2324  case PHASE_FULL_SENDING:
2325  {
2327  "got FULL DONE, finishing\n");
2328  /* We sent the full set, and got the response for that. We're done. */
2329  op->phase = PHASE_FINISHED;
2331  send_client_done (op);
2333  return;
2334  }
2335  break;
2336 
2337  default:
2339  "Handle full done phase is %u\n",
2340  (unsigned) op->phase);
2341  GNUNET_break_op (0);
2342  fail_union_operation (op);
2343  return;
2344  }
2346 }
After sending the full set, wait for responses with the elements that the local peer is missing...
enum IntersectionOperationPhase phase
Current state of the operation.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
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...
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
We sent the strata estimator, and expect an IBF.
#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...
#define LOG(kind,...)
struct GNUNET_CONTAINER_MultiHashMap32 * key_to_element
Maps unsalted IBF-Keys to elements.
Operation context used to execute a set operation.
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
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
static int send_missing_full_elements_iter(void *cls, uint32_t key, void *value)
Iterator over hash map entries, called to destroy the linked list of colliding ibf key entries...
struct GNUNET_CADET_Channel * channel
Channel to the peer.
#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
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
Here is the call graph for this function:

◆ check_union_p2p_demand()

static int check_union_p2p_demand ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Check a demand by the other peer for elements based on a list of struct GNUNET_HashCodes.

cls closure, a set union operation

Parameters
mhthe demand message
Returns
GNUNET_OK if mh is well-formed

Definition at line 2358 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and GNUNET_MessageHeader::size.

2360 {
2361  struct Operation *op = cls;
2362  unsigned int num_hashes;
2363 
2364  (void) op;
2365  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2366  / sizeof(struct GNUNET_HashCode);
2367  if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2368  != num_hashes * sizeof(struct GNUNET_HashCode))
2369  {
2370  GNUNET_break_op (0);
2371  return GNUNET_SYSERR;
2372  }
2373  return GNUNET_OK;
2374 }
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
A 512-bit hashcode.
Operation context used to execute a set operation.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_demand()

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

Handle a demand by the other peer for elements based on a list of struct GNUNET_HashCodes.

cls closure, a set union operation

Parameters
mhthe demand message

Definition at line 2385 of file gnunet-service-setu.c.

References _GSS_is_element_of_operation(), Operation::channel, Set::content, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_Element::element_type, GNUNET_SETU_ElementMessage::element_type, SetContent::elements, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_STATUS_ADD_REMOTE, GNUNET_STATISTICS_update(), LOG, Operation::mq, GNUNET_SETU_ElementMessage::reserved, send_client_element(), Operation::set, GNUNET_SET_Element::size, GNUNET_MessageHeader::size, and Operation::symmetric.

2387 {
2388  struct Operation *op = cls;
2389  struct ElementEntry *ee;
2390  struct GNUNET_SETU_ElementMessage *emsg;
2391  const struct GNUNET_HashCode *hash;
2392  unsigned int num_hashes;
2393  struct GNUNET_MQ_Envelope *ev;
2394 
2395  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2396  / sizeof(struct GNUNET_HashCode);
2397  for (hash = (const struct GNUNET_HashCode *) &mh[1];
2398  num_hashes > 0;
2399  hash++, num_hashes--)
2400  {
2402  hash);
2403  if (NULL == ee)
2404  {
2405  /* Demand for non-existing element. */
2406  GNUNET_break_op (0);
2407  fail_union_operation (op);
2408  return;
2409  }
2410  if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
2411  {
2412  /* Probably confused lazily copied sets. */
2413  GNUNET_break_op (0);
2414  fail_union_operation (op);
2415  return;
2416  }
2417  ev = GNUNET_MQ_msg_extra (emsg,
2418  ee->element.size,
2420  GNUNET_memcpy (&emsg[1],
2421  ee->element.data,
2422  ee->element.size);
2423  emsg->reserved = htons (0);
2424  emsg->element_type = htons (ee->element.element_type);
2426  "[OP %p] Sending demanded element (size %u, hash %s) to peer\n",
2427  op,
2428  (unsigned int) ee->element.size,
2429  GNUNET_h2s (&ee->element_hash));
2430  GNUNET_MQ_send (op->mq, ev);
2432  "# exchanged elements",
2433  1,
2434  GNUNET_NO);
2435  if (op->symmetric)
2436  send_client_element (op,
2437  &ee->element,
2439  }
2441 }
Element should be added to the result set of the remote peer, i.e.
uint16_t reserved
For alignment, always zero.
Definition: setu.h:290
static void send_client_element(struct Operation *op, const struct GNUNET_SETU_Element *element, enum GNUNET_SETU_Status status)
Send a result message to the client indicating that there is a new element.
struct GNUNET_HashCode element_hash
Hash of the element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const void * data
Actual data of the element.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
uint16_t element_type
Type of the element to add or remove.
Definition: setu.h:285
#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
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
Information about an element element in the set.
#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...
A 512-bit hashcode.
int symmetric
GNUNET_YES to also send back set elements we are sending to the remote peer.
#define LOG(kind,...)
Message sent by client to the service to add an element to the set.
Definition: setu.h:275
Operation context used to execute a set operation.
static struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
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 SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
uint16_t size
Number of bytes in the buffer pointed to by data.
struct GNUNET_SET_Element element
The actual element.
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
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
#define GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS
Actual set elements.
uint16_t element_type
Application-specific element type.
Here is the call graph for this function:

◆ check_union_p2p_offer()

static int check_union_p2p_offer ( void *  cls,
const struct GNUNET_MessageHeader mh 
)
static

Check offer (of struct GNUNET_HashCodes).

Parameters
clsthe union operation
mhthe message
Returns
GNUNET_OK if mh is well-formed

Definition at line 2452 of file gnunet-service-setu.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, Operation::phase, PHASE_ACTIVE_DECODING, PHASE_PASSIVE_DECODING, and GNUNET_MessageHeader::size.

2454 {
2455  struct Operation *op = cls;
2456  unsigned int num_hashes;
2457 
2458  /* look up elements and send them */
2459  if ((op->phase != PHASE_PASSIVE_DECODING) &&
2460  (op->phase != PHASE_ACTIVE_DECODING))
2461  {
2462  GNUNET_break_op (0);
2463  return GNUNET_SYSERR;
2464  }
2465  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2466  / sizeof(struct GNUNET_HashCode);
2467  if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)) !=
2468  num_hashes * sizeof(struct GNUNET_HashCode))
2469  {
2470  GNUNET_break_op (0);
2471  return GNUNET_SYSERR;
2472  }
2473  return GNUNET_OK;
2474 }
enum IntersectionOperationPhase phase
Current state of the operation.
The other peer is decoding the IBF we just sent.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
A 512-bit hashcode.
Operation context used to execute a set operation.
We are decoding an IBF.
Header for all communications.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144

◆ handle_union_p2p_offer()

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

Handle offers (of struct GNUNET_HashCodes) and respond with demands (of struct GNUNET_HashCodes).

Parameters
clsthe union operation
mhthe message

Definition at line 2485 of file gnunet-service-setu.c.

References _GSS_is_element_of_operation(), Operation::channel, Set::content, Operation::demanded_hashes, SetContent::elements, GNUNET_assert, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), GNUNET_OK, GNUNET_YES, LOG, Operation::mq, Operation::set, and GNUNET_MessageHeader::size.

2487 {
2488  struct Operation *op = cls;
2489  const struct GNUNET_HashCode *hash;
2490  unsigned int num_hashes;
2491 
2492  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2493  / sizeof(struct GNUNET_HashCode);
2494  for (hash = (const struct GNUNET_HashCode *) &mh[1];
2495  num_hashes > 0;
2496  hash++, num_hashes--)
2497  {
2498  struct ElementEntry *ee;
2499  struct GNUNET_MessageHeader *demands;
2500  struct GNUNET_MQ_Envelope *ev;
2501 
2503  hash);
2504  if (NULL != ee)
2505  if (GNUNET_YES == _GSS_is_element_of_operation (ee, op))
2506  continue;
2507 
2508  if (GNUNET_YES ==
2510  hash))
2511  {
2513  "Skipped sending duplicate demand\n");
2514  continue;
2515  }
2516 
2519  op->demanded_hashes,
2520  hash,
2521  NULL,
2523 
2525  "[OP %p] Requesting element (hash %s)\n",
2526  op, GNUNET_h2s (hash));
2527  ev = GNUNET_MQ_msg_header_extra (demands,
2528  sizeof(struct GNUNET_HashCode),
2530  GNUNET_memcpy (&demands[1],
2531  hash,
2532  sizeof(struct GNUNET_HashCode));
2533  GNUNET_MQ_send (op->mq, ev);
2534  }
2536 }
#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.
struct GNUNET_CONTAINER_MultiHashMap * elements
Maps struct GNUNET_HashCode * to struct ElementEntry *.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
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.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
struct GNUNET_CONTAINER_MultiHashMap * demanded_hashes
Hashes for elements that we have demanded from the other peer.
Information about an element element in the set.
struct Set * set
Set associated with the operation, NULL until the spec has been associated with a set...
A 512-bit hashcode.
#define LOG(kind,...)
#define GNUNET_MQ_msg_header_extra(mh, esize, type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space...
Definition: gnunet_mq_lib.h:88
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.
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 SetContent * content
Content, possibly shared by multiple sets, and thus reference counted.
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
#define GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_MQ_Handle * mq
Message queue for the channel.
static int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
Here is the call graph for this function:

◆ handle_union_p2p_done()

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

Handle a done message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2546 of file gnunet-service-setu.c.

References Operation::channel, fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, LOG, maybe_finish(), Operation::phase, PHASE_ACTIVE_DECODING, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, and PHASE_PASSIVE_DECODING.

2548 {
2549  struct Operation *op = cls;
2550 
2551  switch (op->phase)
2552  {
2554  /* We got all requests, but still have to send our elements in response. */
2557  "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2558  /* The active peer is done sending offers
2559  * and inquiries. This means that all
2560  * our responses to that (demands and offers)
2561  * must be in flight (queued or in mesh).
2562  *
2563  * We should notify the active peer once
2564  * all our demands are satisfied, so that the active
2565  * peer can quit if we gave it everything.
2567  maybe_finish (op);
2568  return;
2569  case PHASE_ACTIVE_DECODING:
2571  "got DONE (as active partner), waiting to finish\n");
2572  /* All demands of the other peer are satisfied,
2573  * and we processed all offers, thus we know
2574  * exactly what our demands must be.
2575  *
2576  * We'll close the channel
2577  * to the other peer once our demands are met.
2578  */op->phase = PHASE_FINISH_CLOSING;
2580  maybe_finish (op);
2581  return;
2582  default:
2583  GNUNET_break_op (0);
2584  fail_union_operation (op);
2585  return;
2586  }
2587 }
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
enum IntersectionOperationPhase phase
Current state of the operation.
The other peer is decoding the IBF we just sent.
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
static void fail_union_operation(struct Operation *op)
Inform the client that the union operation has failed, and proceed to destroy the evaluate operation...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
In the penultimate phase, we wait until all our demands are satisfied.
#define LOG(kind,...)
Operation context used to execute a set operation.
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.
We are decoding an IBF.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
Here is the call graph for this function:

◆ handle_union_p2p_over()

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

Handle a over message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2597 of file gnunet-service-setu.c.

References send_client_done().

2599 {
2600  send_client_done (cls);
2601 }
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
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 2613 of file gnunet-service-setu.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().

2614 {
2615  for (struct Listener *listener = listener_head;
2616  NULL != listener;
2617  listener = listener->next)
2618  {
2619  for (struct Operation *op = listener->op_head;
2620  NULL != op;
2621  op = op->next)
2622  if (op->suggest_id == id)
2623  return op;
2624  }
2625  return NULL;
2626 }
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...
Operation context used to execute a set operation.
static struct Listener * listener_head
Listeners are held in a doubly linked list.
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 2638 of file gnunet-service-setu.c.

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

Referenced by run().

2641 {
2642  struct ClientState *cs;
2643 
2644  num_clients++;
2645  cs = GNUNET_new (struct ClientState);
2646  cs->client = c;
2647  cs->mq = mq;
2648  return cs;
2649 }
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static unsigned int num_clients
Number of active clients.
struct GNUNET_SERVICE_Client * client
Client this is about.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Here is the caller graph for this function:

◆ destroy_elements_iterator()

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

Iterator over hash map entries to free element entries.

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

Definition at line 2661 of file gnunet-service-setu.c.

References GNUNET_free, GNUNET_YES, and value.

Referenced by client_disconnect_cb().

2664 {
2665  struct ElementEntry *ee = value;
2666 
2667  GNUNET_free (ee);
2668  return GNUNET_YES;
2669 }
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 2680 of file gnunet-service-setu.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, ClientState::set, and strata_estimator_destroy().

Referenced by run().

2683 {
2684  struct ClientState *cs = internal_cls;
2685  struct Operation *op;
2686  struct Listener *listener;
2687  struct Set *set;
2688 
2690  "Client disconnected, cleaning up\n");
2691  if (NULL != (set = cs->set))
2692  {
2693  struct SetContent *content = set->content;
2694 
2696  "Destroying client's set\n");
2697  /* Destroy pending set operations */
2698  while (NULL != set->ops_head)
2699  _GSS_operation_destroy (set->ops_head);
2700 
2701  /* Destroy operation-specific state */
2702  if (NULL != set->se)
2703  {
2704  strata_estimator_destroy (set->se);
2705  set->se = NULL;
2706  }
2707  /* free set content (or at least decrement RC) */
2708  set->content = NULL;
2709  GNUNET_assert (0 != content->refcount);
2710  content->refcount--;
2711  if (0 == content->refcount)
2712  {
2713  GNUNET_assert (NULL != content->elements);
2716  NULL);
2718  content->elements = NULL;
2719  GNUNET_free (content);
2720  }
2721  GNUNET_free (set);
2722  }
2723 
2724  if (NULL != (listener = cs->listener))
2725  {
2727  "Destroying client's listener\n");
2728  GNUNET_CADET_close_port (listener->open_port);
2729  listener->open_port = NULL;
2730  while (NULL != (op = listener->op_head))
2731  {
2733  "Destroying incoming operation `%u' from peer `%s'\n",
2734  (unsigned int) op->client_request_id,
2735  GNUNET_i2s (&op->peer));
2736  incoming_destroy (op);
2737  }
2739  listener_tail,
2740  listener);
2741  GNUNET_free (listener);
2742  }
2743  GNUNET_free (cs);
2744  num_clients--;
2745  if ( (GNUNET_YES == in_shutdown) &&
2746  (0 == num_clients) )
2747  {
2748  if (NULL != cadet)
2749  {
2751  cadet = NULL;
2752  }
2753  }
2754 }
#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.
unsigned int refcount
Number of references to the content.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct Listener * listener_tail
Listeners are held in a doubly linked list.
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 *.
static struct GNUNET_CADET_Handle * cadet
Handle to the cadet service, used to listen for and connect to remote peers.
A listener is inhabited by a client, and waits for evaluation requests from remote peers...
static unsigned int num_clients
Number of active clients.
static void _GSS_operation_destroy(struct Operation *op)
Destroy the given operation.
struct GNUNET_PeerIdentity peer
The identity of the requesting peer.
static int destroy_elements_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries to free element entries.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
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 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...
static void incoming_destroy(struct Operation *op)
Destroy an incoming request from a remote peer.
uint32_t client_request_id
ID used to identify an operation between service and client.
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 Listener * listener_head
Listeners are held in a doubly linked list.
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 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.
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 2766 of file gnunet-service-setu.c.

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

2768 {
2769  struct Operation *op = cls;
2770  struct Listener *listener = op->listener;
2771  const struct GNUNET_MessageHeader *nested_context;
2772 
2773  /* double operation request */
2774  if (0 != op->suggest_id)
2775  {
2776  GNUNET_break_op (0);
2777  return GNUNET_SYSERR;
2778  }
2779  /* This should be equivalent to the previous condition, but can't hurt to check twice */
2780  if (NULL == listener)
2781  {
2782  GNUNET_break (0);
2783  return GNUNET_SYSERR;
2784  }
2785  nested_context = GNUNET_MQ_extract_nested_mh (msg);
2786  if ((NULL != nested_context) &&
2787  (ntohs (nested_context->size) > GNUNET_SETU_CONTEXT_MESSAGE_MAX_SIZE))
2788  {
2789  GNUNET_break_op (0);
2790  return GNUNET_SYSERR;
2791  }
2792  return GNUNET_OK;
2793 }
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.
#define GNUNET_SETU_CONTEXT_MESSAGE_MAX_SIZE
Maximum size of a context message for set operation requests.
Operation context used to execute a set operation.
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

Definition at line 2812 of file gnunet-service-setu.c.

References GNUNET_SETU_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_SETU_REQUEST, GNUNET_MQ_extract_nested_mh, GNUNET_MQ_msg_nested_mh, GNUNET_MQ_send(), GNUNET_SCHEDULER_cancel(), Operation::listener, ClientState::mq, Operation::peer, GNUNET_SETU_RequestMessage::peer_id, Operation::remote_element_count, Operation::suggest_id, suggest_id, and Operation::timeout_task.

2814 {
2815  struct Operation *op = cls;
2816  struct Listener *listener = op->listener;
2817  const struct GNUNET_MessageHeader *nested_context;
2818  struct GNUNET_MQ_Envelope *env;
2819  struct GNUNET_SETU_RequestMessage *cmsg;
2820 
2821  nested_context = GNUNET_MQ_extract_nested_mh (msg);
2822  /* Make a copy of the nested_context (application-specific context
2823  information that is opaque to set) so we can pass it to the
2824  listener later on */
2825  if (NULL != nested_context)
2826  op->context_msg = GNUNET_copy_message (nested_context);
2827  op->remote_element_count = ntohl (msg->element_count);
2828  GNUNET_log (
2830  "Received P2P operation request (port %s) for active listener\n",
2831  GNUNET_h2s (&op->listener->app_id));
2832  GNUNET_assert (0 == op->suggest_id);
2833  if (0 == suggest_id)
2834  suggest_id++;
2835  op->suggest_id = suggest_id++;
2836  GNUNET_assert (NULL != op->timeout_task);
2838  op->timeout_task = NULL;
2839  env = GNUNET_MQ_msg_nested_mh (cmsg,
2841  op->context_msg);
2842  GNUNET_log (
2844  "Suggesting incoming request with accept id %u to listener %p of client %p\n",
2845  op->suggest_id,
2846  listener,
2847  listener->cs);
2848  cmsg->accept_id = htonl (op->suggest_id);
2849  cmsg->peer_id = op->peer;
2850  GNUNET_MQ_send (listener->cs->mq,
2851  env);
2852  /* NOTE: GNUNET_CADET_receive_done() will be called in
2853  #handle_client_accept() */
2854 }
#define GNUNET_MESSAGE_TYPE_SETU_REQUEST
Notify the client of an incoming request from a remote peer.
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...
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.
uint32_t accept_id
ID of the to identify the request when accepting or rejecting it.
Definition: setu.h:159
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Operation context used to execute a set operation.
A request for an operation with another client.
Definition: setu.h:148
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: setu.h:164
#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
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_SETU_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 2866 of file gnunet-service-setu.c.

References ClientState::client, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_YES, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, ClientState::set, and strata_estimator_create().

2868 {
2869  struct ClientState *cs = cls;
2870  struct Set *set;
2871 
2873  "Client created new set for union operation\n");
2874  if (NULL != cs->set)
2875  {
2876  /* There can only be one set per client */
2877  GNUNET_break (0);
2879  return;
2880  }
2881  set = GNUNET_new (struct Set);
2882  {
2883  struct StrataEstimator *se;
2884 
2886  SE_IBF_SIZE,
2887  SE_IBF_HASH_NUM);
2888  if (NULL == se)
2889  {
2891  "Failed to allocate strata estimator\n");
2892  GNUNET_free (set);
2894  return;
2895  }
2896  set->se = se;
2897  }
2898  set->content = GNUNET_new (struct SetContent);
2899  set->content->refcount = 1;
2900  set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
2901  GNUNET_YES);
2902  set->cs = cs;
2903  cs->set = set;
2905 }
struct Set * set
Set, if associated with the client, otherwise NULL.
State we keep per client.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
struct StrataEstimator * strata_estimator_create(unsigned int strata_count, uint32_t ibf_size, uint8_t ibf_hashnum)
Create a new strata estimator with the given parameters.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
A handle to a strata estimator.
A set that supports a specific operation with other peers.
Definition: