GNUnet  0.19.5
gnunet-service-set_union.h File Reference

two-peer set operations More...

Include dependency graph for gnunet-service-set_union.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int check_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
void handle_union_p2p_strata_estimator (void *cls, const struct StrataEstimatorMessage *msg)
 Handle a strata estimator from a remote peer. More...
 
int check_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Check an IBF message from a remote peer. More...
 
void handle_union_p2p_ibf (void *cls, const struct IBFMessage *msg)
 Handle an IBF message from a remote peer. More...
 
int check_union_p2p_elements (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Check an element message from a remote peer. More...
 
void handle_union_p2p_elements (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
int check_union_p2p_full_element (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Check a full element message from a remote peer. More...
 
void handle_union_p2p_full_element (void *cls, const struct GNUNET_SET_ElementMessage *emsg)
 Handle an element message from a remote peer. More...
 
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...
 
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...
 
void handle_union_p2p_request_full (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a request for full set transmission. More...
 
void handle_union_p2p_full_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a "full done" message. More...
 
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...
 
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...
 
int check_union_p2p_offer (void *cls, const struct GNUNET_MessageHeader *mh)
 Check offer (of struct GNUNET_HashCodes). More...
 
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...
 
void handle_union_p2p_done (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle a done message from a remote peer. More...
 
void handle_union_p2p_over (void *cls, const struct GNUNET_MessageHeader *mh)
 Handle an over message from a remote peer. More...
 

Detailed Description

two-peer set operations

Author
Florian Dold
Christian Grothoff

Definition in file gnunet-service-set_union.h.

Function Documentation

◆ check_union_p2p_strata_estimator()

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

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 821 of file gnunet-service-set_union.c.

823 {
824  struct Operation *op = cls;
825  int is_compressed;
826  size_t len;
827 
828  if (op->state->phase != PHASE_EXPECT_SE)
829  {
830  GNUNET_break (0);
831  return GNUNET_SYSERR;
832  }
833  is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons (
834  msg->header.type));
835  len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
836  if ((GNUNET_NO == is_compressed) &&
838  {
839  GNUNET_break (0);
840  return GNUNET_SYSERR;
841  }
842  return GNUNET_OK;
843 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define SE_IBF_SIZE
Size of the IBFs in the strata estimator.
#define SE_STRATA_COUNT
Number of IBFs in a strata estimator.
@ PHASE_EXPECT_SE
We sent the request message, and expect a strata estimator.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#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_SET_UNION_P2P_SEC
Compressed strata estimator.
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition: ibf.h:72
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Operation context used to execute a set operation.
Strata estimator together with the peer's overall set size.

References GNUNET_break, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, IBF_BUCKET_SIZE, len, msg, op, PHASE_EXPECT_SE, SE_IBF_SIZE, SE_STRATA_COUNT, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

◆ handle_union_p2p_strata_estimator()

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

Handle a strata estimator from a remote peer.

Parameters
clsthe union operation
msgthe message

Definition at line 853 of file gnunet-service-set_union.c.

855 {
856  struct Operation *op = cls;
857  struct StrataEstimator *remote_se;
858  unsigned int diff;
859  uint64_t other_size;
860  size_t len;
861  int is_compressed;
862 
863  is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons (
864  msg->header.type));
866  "# bytes of SE received",
867  ntohs (msg->header.size),
868  GNUNET_NO);
869  len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
870  other_size = GNUNET_ntohll (msg->set_size);
872  SE_IBF_SIZE,
874  if (NULL == remote_se)
875  {
876  /* insufficient resources, fail */
878  return;
879  }
880  if (GNUNET_OK !=
882  len,
883  is_compressed,
884  remote_se))
885  {
886  /* decompression failed */
887  strata_estimator_destroy (remote_se);
889  return;
890  }
891  GNUNET_assert (NULL != op->state->se);
892  diff = strata_estimator_difference (remote_se,
893  op->state->se);
894 
895  if (diff > 200)
896  diff = diff * 3 / 2;
897 
898  strata_estimator_destroy (remote_se);
899  strata_estimator_destroy (op->state->se);
900  op->state->se = NULL;
902  "got se diff=%d, using ibf size %d\n",
903  diff,
904  1U << get_order_from_difference (diff));
905 
906  {
907  char *set_debug;
908 
909  set_debug = getenv ("GNUNET_SET_BENCHMARK");
910  if ((NULL != set_debug) &&
911  (0 == strcmp (set_debug, "1")))
912  {
913  FILE *f = fopen ("set.log", "a");
914  fprintf (f, "%llu\n", (unsigned long long) diff);
915  fclose (f);
916  }
917  }
918 
919  if ((GNUNET_YES == op->byzantine) &&
920  (other_size < op->byzantine_lower_bound))
921  {
922  GNUNET_break (0);
924  return;
925  }
926 
927  if ((GNUNET_YES == op->force_full) ||
928  (diff > op->state->initial_size / 4) ||
929  (0 == other_size))
930  {
932  "Deciding to go for full set transmission (diff=%d, own set=%llu)\n",
933  diff,
934  (unsigned long long) op->state->initial_size);
936  "# of full sends",
937  1,
938  GNUNET_NO);
939  if ((op->state->initial_size <= other_size) ||
940  (0 == other_size))
941  {
942  send_full_set (op);
943  }
944  else
945  {
946  struct GNUNET_MQ_Envelope *ev;
947 
949  "Telling other peer that we expect its full set\n");
950  op->state->phase = PHASE_EXPECT_IBF;
951  ev = GNUNET_MQ_msg_header (
953  GNUNET_MQ_send (op->mq,
954  ev);
955  }
956  }
957  else
958  {
960  "# of ibf sends",
961  1,
962  GNUNET_NO);
963  if (GNUNET_OK !=
964  send_ibf (op,
966  {
967  /* Internal error, best we can do is shut the connection */
969  "Failed to send IBF, closing connection\n");
971  return;
972  }
973  }
974  GNUNET_CADET_receive_done (op->channel);
975 }
char * getenv()
struct GNUNET_STATISTICS_Handle * _GSS_statistics
Statistics handle.
static void send_full_set(struct Operation *op)
Switch to full set transmission for op.
static int send_ibf(struct Operation *op, uint16_t ibf_order)
Send an ibf of appropriate size.
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 LOG(kind,...)
@ PHASE_EXPECT_IBF
We sent the strata estimator, and expect an IBF.
#define SE_IBF_HASH_NUM
The hash num parameter for the difference digests and strata estimators.
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.
unsigned int strata_estimator_difference(const struct StrataEstimator *se1, const struct StrataEstimator *se2)
Estimate set difference with two strata estimators, i.e.
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.
void strata_estimator_destroy(struct StrataEstimator *se)
Destroy a strata estimator, free all of its resources.
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.
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:872
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
@ GNUNET_YES
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
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:304
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:87
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL
Demand the whole element from the other peer, given only the hash code.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
A handle to a strata estimator.

References _GSS_statistics, removetrailingwhitespace::f, fail_union_operation(), 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_SET_UNION_P2P_REQUEST_FULL, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC, GNUNET_MQ_msg_header, GNUNET_MQ_send(), GNUNET_NO, GNUNET_ntohll(), GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, len, LOG, msg, op, PHASE_EXPECT_IBF, SE_IBF_HASH_NUM, SE_IBF_SIZE, SE_STRATA_COUNT, send_full_set(), send_ibf(), GNUNET_MessageHeader::size, strata_estimator_create(), strata_estimator_destroy(), strata_estimator_difference(), strata_estimator_read(), and GNUNET_MessageHeader::type.

Here is the call graph for this function:

◆ check_union_p2p_ibf()

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

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 1210 of file gnunet-service-set_union.c.

1212 {
1213  struct Operation *op = cls;
1214  unsigned int buckets_in_message;
1215 
1216  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1217  {
1218  GNUNET_break_op (0);
1219  return GNUNET_SYSERR;
1220  }
1221  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1222  / IBF_BUCKET_SIZE;
1223  if (0 == buckets_in_message)
1224  {
1225  GNUNET_break_op (0);
1226  return GNUNET_SYSERR;
1227  }
1228  if ((ntohs (msg->header.size) - sizeof *msg) != buckets_in_message
1229  * IBF_BUCKET_SIZE)
1230  {
1231  GNUNET_break_op (0);
1232  return GNUNET_SYSERR;
1233  }
1234  if (op->state->phase == PHASE_EXPECT_IBF_CONT)
1235  {
1236  if (ntohl (msg->offset) != op->state->ibf_buckets_received)
1237  {
1238  GNUNET_break_op (0);
1239  return GNUNET_SYSERR;
1240  }
1241  if (1 << msg->order != op->state->remote_ibf->size)
1242  {
1243  GNUNET_break_op (0);
1244  return GNUNET_SYSERR;
1245  }
1246  if (ntohl (msg->salt) != op->state->salt_receive)
1247  {
1248  GNUNET_break_op (0);
1249  return GNUNET_SYSERR;
1250  }
1251  }
1252  else if ((op->state->phase != PHASE_INVENTORY_PASSIVE) &&
1253  (op->state->phase != PHASE_EXPECT_IBF))
1254  {
1255  GNUNET_break_op (0);
1256  return GNUNET_SYSERR;
1257  }
1258 
1259  return GNUNET_OK;
1260 }
@ PHASE_INVENTORY_PASSIVE
The other peer is decoding the IBF we just sent.
@ PHASE_EXPECT_IBF_CONT
Continuation for multi part IBFs.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
@ GNUNET_SET_OPERATION_UNION
Set union, return all elements that are in at least one of the sets.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, IBF_BUCKET_SIZE, msg, op, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_PASSIVE, and GNUNET_MessageHeader::size.

◆ handle_union_p2p_ibf()

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

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 1273 of file gnunet-service-set_union.c.

1275 {
1276  struct Operation *op = cls;
1277  unsigned int buckets_in_message;
1278 
1279  buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1280  / IBF_BUCKET_SIZE;
1281  if ((op->state->phase == PHASE_INVENTORY_PASSIVE) ||
1282  (op->state->phase == PHASE_EXPECT_IBF))
1283  {
1284  op->state->phase = PHASE_EXPECT_IBF_CONT;
1285  GNUNET_assert (NULL == op->state->remote_ibf);
1287  "Creating new ibf of size %u\n",
1288  1 << msg->order);
1289  op->state->remote_ibf = ibf_create (1 << msg->order, SE_IBF_HASH_NUM);
1290  op->state->salt_receive = ntohl (msg->salt);
1292  "Receiving new IBF with salt %u\n",
1293  op->state->salt_receive);
1294  if (NULL == op->state->remote_ibf)
1295  {
1297  "Failed to parse remote IBF, closing connection\n");
1299  return;
1300  }
1301  op->state->ibf_buckets_received = 0;
1302  if (0 != ntohl (msg->offset))
1303  {
1304  GNUNET_break_op (0);
1306  return;
1307  }
1308  }
1309  else
1310  {
1311  GNUNET_assert (op->state->phase == PHASE_EXPECT_IBF_CONT);
1313  "Received more of IBF\n");
1314  }
1315  GNUNET_assert (NULL != op->state->remote_ibf);
1316 
1317  ibf_read_slice (&msg[1],
1318  op->state->ibf_buckets_received,
1319  buckets_in_message,
1320  op->state->remote_ibf);
1321  op->state->ibf_buckets_received += buckets_in_message;
1322 
1323  if (op->state->ibf_buckets_received == op->state->remote_ibf->size)
1324  {
1326  "received full ibf\n");
1327  op->state->phase = PHASE_INVENTORY_ACTIVE;
1328  if (GNUNET_OK !=
1329  decode_and_send (op))
1330  {
1331  /* Internal error, best we can do is shut down */
1333  "Failed to decode IBF, closing connection\n");
1335  return;
1336  }
1337  }
1338  GNUNET_CADET_receive_done (op->channel);
1339 }
static int decode_and_send(struct Operation *op)
Decode which elements are missing on each side, and send the appropriate offers and inquiries.
@ PHASE_INVENTORY_ACTIVE
We are decoding an IBF.
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:324
struct InvertibleBloomFilter * ibf_create(uint32_t size, uint8_t hash_num)
Create an invertible bloom filter.
Definition: ibf.c:80

References 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, IBF_BUCKET_SIZE, ibf_create(), ibf_read_slice(), LOG, msg, op, PHASE_EXPECT_IBF, PHASE_EXPECT_IBF_CONT, PHASE_INVENTORY_ACTIVE, PHASE_INVENTORY_PASSIVE, SE_IBF_HASH_NUM, and GNUNET_MessageHeader::size.

Here is the call graph for this function:

◆ check_union_p2p_elements()

int check_union_p2p_elements ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

Check an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1489 of file gnunet-service-set_union.c.

1491 {
1492  struct Operation *op = cls;
1493 
1494  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1495  {
1496  GNUNET_break_op (0);
1497  return GNUNET_SYSERR;
1498  }
1499  if (0 == GNUNET_CONTAINER_multihashmap_size (op->state->demanded_hashes))
1500  {
1501  GNUNET_break_op (0);
1502  return GNUNET_SYSERR;
1503  }
1504  return GNUNET_OK;
1505 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.

References GNUNET_break_op, GNUNET_CONTAINER_multihashmap_size(), GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, and op.

Here is the call graph for this function:

◆ handle_union_p2p_elements()

void handle_union_p2p_elements ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

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 1517 of file gnunet-service-set_union.c.

1519 {
1520  struct Operation *op = cls;
1521  struct ElementEntry *ee;
1522  struct KeyEntry *ke;
1523  uint16_t element_size;
1524 
1525  element_size = ntohs (emsg->header.size) - sizeof(struct
1527  ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
1528  GNUNET_memcpy (&ee[1],
1529  &emsg[1],
1530  element_size);
1531  ee->element.size = element_size;
1532  ee->element.data = &ee[1];
1533  ee->element.element_type = ntohs (emsg->element_type);
1534  ee->remote = GNUNET_YES;
1536  &ee->element_hash);
1537  if (GNUNET_NO ==
1538  GNUNET_CONTAINER_multihashmap_remove (op->state->demanded_hashes,
1539  &ee->element_hash,
1540  NULL))
1541  {
1542  /* We got something we didn't demand, since it's not in our map. */
1543  GNUNET_break_op (0);
1545  return;
1546  }
1547 
1549  "Got element (size %u, hash %s) from peer\n",
1550  (unsigned int) element_size,
1551  GNUNET_h2s (&ee->element_hash));
1552 
1554  "# received elements",
1555  1,
1556  GNUNET_NO);
1558  "# exchanged elements",
1559  1,
1560  GNUNET_NO);
1561 
1562  op->state->received_total++;
1563 
1564  ke = op_get_element (op, &ee->element_hash);
1565  if (NULL != ke)
1566  {
1567  /* Got repeated element. Should not happen since
1568  * we track demands. */
1570  "# repeated elements",
1571  1,
1572  GNUNET_NO);
1573  ke->received = GNUNET_YES;
1574  GNUNET_free (ee);
1575  }
1576  else
1577  {
1579  "Registering new element from remote peer\n");
1580  op->state->received_fresh++;
1582  /* only send results immediately if the client wants it */
1583  switch (op->result_mode)
1584  {
1587  break;
1588 
1591  break;
1592 
1593  default:
1594  /* Result mode not supported, should have been caught earlier. */
1595  GNUNET_break (0);
1596  break;
1597  }
1598  }
1599 
1600  if ((op->state->received_total > 8) &&
1601  (op->state->received_fresh < op->state->received_total / 3))
1602  {
1603  /* The other peer gave us lots of old elements, there's something wrong. */
1604  GNUNET_break_op (0);
1606  return;
1607  }
1608  GNUNET_CADET_receive_done (op->channel);
1609  maybe_finish (op);
1610 }
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's element set.
static void maybe_finish(struct Operation *op)
Tests if the operation is finished, and if so notify.
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.
static void send_client_element(struct Operation *op, struct GNUNET_SET_Element *element, int status)
Send a result message to the client indicating that there is a new element.
static unsigned int element_size
enum GNUNET_GenericReturnValue 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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_SET_element_hash(const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash)
Hash a set element.
Definition: set_api.c:1184
@ GNUNET_SET_STATUS_OK
Everything went ok, we are transmitting an element of the result (in set, or to be removed from set,...
@ GNUNET_SET_STATUS_ADD_LOCAL
Element should be added to the result set of the local peer, i.e.
@ GNUNET_SET_RESULT_SYMMETRIC
Client gets notified of the required changes for both the local and the remote set.
@ GNUNET_SET_RESULT_ADDED
Client gets only elements that have been added to the set.
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's set.
struct GNUNET_SET_Element element
The actual element.
struct GNUNET_HashCode element_hash
Hash of the element.
Message sent by client to the service to add or remove an element to/from the set.
Definition: set.h:281
uint16_t element_type
Type of the element to add or remove.
Definition: set.h:291
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_SET_ADD or GNUNET_MESSAGE_TYPE_SET_REMOVE.
Definition: set.h:286
uint16_t size
Number of bytes in the buffer pointed to by data.
const void * data
Actual data of the element.
uint16_t element_type
Application-specific element type.
The key entry is used to associate an ibf key with an element.
int received
Did we receive this element? Even if element->is_foreign is false, we might have received the element...

References _GSS_statistics, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, fail_union_operation(), GNUNET_break, 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_SET_element_hash(), GNUNET_SET_RESULT_ADDED, GNUNET_SET_RESULT_SYMMETRIC, GNUNET_SET_STATUS_ADD_LOCAL, GNUNET_SET_STATUS_OK, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SET_ElementMessage::header, LOG, maybe_finish(), op, op_get_element(), op_register_element(), KeyEntry::received, ElementEntry::remote, send_client_element(), GNUNET_MessageHeader::size, and GNUNET_SET_Element::size.

Here is the call graph for this function:

◆ check_union_p2p_full_element()

int check_union_p2p_full_element ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

Check a full element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1620 of file gnunet-service-set_union.c.

1622 {
1623  struct Operation *op = cls;
1624 
1625  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1626  {
1627  GNUNET_break_op (0);
1628  return GNUNET_SYSERR;
1629  }
1630  // FIXME: check that we expect full elements here?
1631  return GNUNET_OK;
1632 }

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, and op.

◆ handle_union_p2p_full_element()

void handle_union_p2p_full_element ( void *  cls,
const struct GNUNET_SET_ElementMessage emsg 
)

Handle an element message from a remote peer.

Parameters
clsthe union operation
emsgthe message

Definition at line 1642 of file gnunet-service-set_union.c.

1644 {
1645  struct Operation *op = cls;
1646  struct ElementEntry *ee;
1647  struct KeyEntry *ke;
1648  uint16_t element_size;
1649 
1650  element_size = ntohs (emsg->header.size) - sizeof(struct
1652  ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
1653  GNUNET_memcpy (&ee[1], &emsg[1], element_size);
1654  ee->element.size = element_size;
1655  ee->element.data = &ee[1];
1656  ee->element.element_type = ntohs (emsg->element_type);
1657  ee->remote = GNUNET_YES;
1659 
1661  "Got element (full diff, size %u, hash %s) from peer\n",
1662  (unsigned int) element_size,
1663  GNUNET_h2s (&ee->element_hash));
1664 
1666  "# received elements",
1667  1,
1668  GNUNET_NO);
1670  "# exchanged elements",
1671  1,
1672  GNUNET_NO);
1673 
1674  op->state->received_total++;
1675 
1676  ke = op_get_element (op, &ee->element_hash);
1677  if (NULL != ke)
1678  {
1679  /* Got repeated element. Should not happen since
1680  * we track demands. */
1682  "# repeated elements",
1683  1,
1684  GNUNET_NO);
1685  ke->received = GNUNET_YES;
1686  GNUNET_free (ee);
1687  }
1688  else
1689  {
1691  "Registering new element from remote peer\n");
1692  op->state->received_fresh++;
1694  /* only send results immediately if the client wants it */
1695  switch (op->result_mode)
1696  {
1699  break;
1700 
1703  break;
1704 
1705  default:
1706  /* Result mode not supported, should have been caught earlier. */
1707  GNUNET_break (0);
1708  break;
1709  }
1710  }
1711 
1712  if ((GNUNET_YES == op->byzantine) &&
1713  (op->state->received_total > 384 + op->state->received_fresh * 4) &&
1714  (op->state->received_fresh < op->state->received_total / 6))
1715  {
1716  /* The other peer gave us lots of old elements, there's something wrong. */
1718  "Other peer sent only %llu/%llu fresh elements, failing operation\n",
1719  (unsigned long long) op->state->received_fresh,
1720  (unsigned long long) op->state->received_total);
1721  GNUNET_break_op (0);
1723  return;
1724  }
1725  GNUNET_CADET_receive_done (op->channel);
1726 }

References _GSS_statistics, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, element_size, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, fail_union_operation(), GNUNET_break, 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_SET_element_hash(), GNUNET_SET_RESULT_ADDED, GNUNET_SET_RESULT_SYMMETRIC, GNUNET_SET_STATUS_ADD_LOCAL, GNUNET_SET_STATUS_OK, GNUNET_STATISTICS_update(), GNUNET_YES, GNUNET_SET_ElementMessage::header, LOG, op, op_get_element(), op_register_element(), KeyEntry::received, ElementEntry::remote, send_client_element(), GNUNET_MessageHeader::size, and GNUNET_SET_Element::size.

Here is the call graph for this function:

◆ check_union_p2p_inquiry()

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

Parameters
clsthe union operation
msgthe message

Definition at line 1737 of file gnunet-service-set_union.c.

1739 {
1740  struct Operation *op = cls;
1741  unsigned int num_keys;
1742 
1743  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1744  {
1745  GNUNET_break_op (0);
1746  return GNUNET_SYSERR;
1747  }
1748  if (op->state->phase != PHASE_INVENTORY_PASSIVE)
1749  {
1750  GNUNET_break_op (0);
1751  return GNUNET_SYSERR;
1752  }
1753  num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
1754  / sizeof(struct IBF_Key);
1755  if ((ntohs (msg->header.size) - sizeof(struct InquiryMessage))
1756  != num_keys * sizeof(struct IBF_Key))
1757  {
1758  GNUNET_break_op (0);
1759  return GNUNET_SYSERR;
1760  }
1761  return GNUNET_OK;
1762 }
Keys that can be inserted into and removed from an IBF.
Definition: ibf.h:46
estimate_best_mode_of_operation (uint64_t avg_element_size, uint64_t local_set_size,...

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, msg, op, PHASE_INVENTORY_PASSIVE, and GNUNET_MessageHeader::size.

◆ handle_union_p2p_inquiry()

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

Parameters
clsthe union operation
msgthe message

Definition at line 1773 of file gnunet-service-set_union.c.

1775 {
1776  struct Operation *op = cls;
1777  const struct IBF_Key *ibf_key;
1778  unsigned int num_keys;
1779 
1781  "Received union inquiry\n");
1782  num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
1783  / sizeof(struct IBF_Key);
1784  ibf_key = (const struct IBF_Key *) &msg[1];
1785  while (0 != num_keys--)
1786  {
1787  struct IBF_Key unsalted_key;
1788 
1789  unsalt_key (ibf_key,
1790  ntohl (msg->salt),
1791  &unsalted_key);
1793  unsalted_key);
1794  ibf_key++;
1795  }
1796  GNUNET_CADET_receive_done (op->channel);
1797 }
static void unsalt_key(const struct IBF_Key *k_in, uint32_t salt, struct IBF_Key *k_out)
FIXME.
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.

References GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, LOG, msg, op, send_offers_for_key(), GNUNET_MessageHeader::size, and unsalt_key().

Here is the call graph for this function:

◆ handle_union_p2p_request_full()

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

Handle a request for full set transmission.

Parameters
clsclosure, a set union operation
mhthe demand message

Definition at line 1843 of file gnunet-service-set_union.c.

1845 {
1846  struct Operation *op = cls;
1847 
1849  "Received request for full set transmission\n");
1850  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1851  {
1852  GNUNET_break_op (0);
1854  return;
1855  }
1856  if (PHASE_EXPECT_IBF != op->state->phase)
1857  {
1858  GNUNET_break_op (0);
1860  return;
1861  }
1862 
1863  // FIXME: we need to check that our set is larger than the
1864  // byzantine_lower_bound by some threshold
1865  send_full_set (op);
1866  GNUNET_CADET_receive_done (op->channel);
1867 }

References fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SET_OPERATION_UNION, LOG, op, PHASE_EXPECT_IBF, and send_full_set().

Here is the call graph for this function:

◆ handle_union_p2p_full_done()

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

Handle a "full done" message.

Parameters
clsclosure, a set union operation
mhthe demand message

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

1879 {
1880  struct Operation *op = cls;
1881 
1882  switch (op->state->phase)
1883  {
1884  case PHASE_EXPECT_IBF:
1885  {
1886  struct GNUNET_MQ_Envelope *ev;
1887 
1889  "got FULL DONE, sending elements that other peer is missing\n");
1890 
1891  /* send all the elements that did not come from the remote peer */
1892  GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element,
1894  op);
1895 
1897  GNUNET_MQ_send (op->mq,
1898  ev);
1899  op->state->phase = PHASE_DONE;
1900  /* we now wait until the other peer sends us the OVER message*/
1901  }
1902  break;
1903 
1904  case PHASE_FULL_SENDING:
1905  {
1907  "got FULL DONE, finishing\n");
1908  /* We sent the full set, and got the response for that. We're done. */
1909  op->state->phase = PHASE_DONE;
1910  GNUNET_CADET_receive_done (op->channel);
1911  send_client_done (op);
1913  return;
1914  }
1915  break;
1916 
1917  default:
1919  "Handle full done phase is %u\n",
1920  (unsigned) op->state->phase);
1921  GNUNET_break_op (0);
1923  return;
1924  }
1925  GNUNET_CADET_receive_done (op->channel);
1926 }
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 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.
static void send_client_done(void *cls)
Signal to the client that the operation has finished and destroy the operation.
@ PHASE_DONE
In the ultimate phase, we wait until our demands are satisfied and then quit (sending another DONE me...
@ PHASE_FULL_SENDING
After sending the full set, wait for responses with the elements that the local peer is missing.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE
Request all missing elements from the other peer, based on their sets and the elements we previously ...

References _GSS_operation_destroy2(), fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, GNUNET_MQ_msg_header, GNUNET_MQ_send(), LOG, op, PHASE_DONE, PHASE_EXPECT_IBF, PHASE_FULL_SENDING, send_client_done(), and send_missing_full_elements_iter().

Here is the call graph for this function:

◆ check_union_p2p_demand()

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.

Parameters
clsclosure, a set union operation
mhthe demand message
Returns
GNUNET_OK if mh is well-formed

Definition at line 1938 of file gnunet-service-set_union.c.

1940 {
1941  struct Operation *op = cls;
1942  unsigned int num_hashes;
1943 
1944  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1945  {
1946  GNUNET_break_op (0);
1947  return GNUNET_SYSERR;
1948  }
1949  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
1950  / sizeof(struct GNUNET_HashCode);
1951  if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
1952  != num_hashes * sizeof(struct GNUNET_HashCode))
1953  {
1954  GNUNET_break_op (0);
1955  return GNUNET_SYSERR;
1956  }
1957  return GNUNET_OK;
1958 }
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
A 512-bit hashcode.
Header for all communications.

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, mh, and op.

◆ handle_union_p2p_demand()

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.

Parameters
clsclosure, a set union operation
mhthe demand message

Definition at line 1969 of file gnunet-service-set_union.c.

1971 {
1972  struct Operation *op = cls;
1973  struct ElementEntry *ee;
1974  struct GNUNET_SET_ElementMessage *emsg;
1975  const struct GNUNET_HashCode *hash;
1976  unsigned int num_hashes;
1977  struct GNUNET_MQ_Envelope *ev;
1978 
1979  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
1980  / sizeof(struct GNUNET_HashCode);
1981  for (hash = (const struct GNUNET_HashCode *) &mh[1];
1982  num_hashes > 0;
1983  hash++, num_hashes--)
1984  {
1985  ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
1986  hash);
1987  if (NULL == ee)
1988  {
1989  /* Demand for non-existing element. */
1990  GNUNET_break_op (0);
1992  return;
1993  }
1995  {
1996  /* Probably confused lazily copied sets. */
1997  GNUNET_break_op (0);
1999  return;
2000  }
2001  ev = GNUNET_MQ_msg_extra (emsg, ee->element.size,
2003  GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size);
2004  emsg->reserved = htons (0);
2005  emsg->element_type = htons (ee->element.element_type);
2007  "[OP %p] Sending demanded element (size %u, hash %s) to peer\n",
2008  op,
2009  (unsigned int) ee->element.size,
2010  GNUNET_h2s (&ee->element_hash));
2011  GNUNET_MQ_send (op->mq, ev);
2013  "# exchanged elements",
2014  1,
2015  GNUNET_NO);
2016 
2017  switch (op->result_mode)
2018  {
2020  /* Nothing to do. */
2021  break;
2022 
2025  break;
2026 
2027  default:
2028  /* Result mode not supported, should have been caught earlier. */
2029  GNUNET_break (0);
2030  break;
2031  }
2032  }
2033  GNUNET_CADET_receive_done (op->channel);
2034 }
int _GSS_is_element_of_operation(struct ElementEntry *ee, struct Operation *op)
Is element ee part of the set used by op?
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.
#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:63
#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
Actual set elements.
@ GNUNET_SET_STATUS_ADD_REMOTE
Element should be added to the result set of the remote peer, i.e.
uint16_t reserved
For alignment, always zero.
Definition: set.h:296

References _GSS_is_element_of_operation(), _GSS_statistics, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_Element::element_type, GNUNET_SET_ElementMessage::element_type, fail_union_operation(), GNUNET_break, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SET_RESULT_ADDED, GNUNET_SET_RESULT_SYMMETRIC, GNUNET_SET_STATUS_ADD_REMOTE, GNUNET_STATISTICS_update(), LOG, mh, op, GNUNET_SET_ElementMessage::reserved, send_client_element(), and GNUNET_SET_Element::size.

Here is the call graph for this function:

◆ check_union_p2p_offer()

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

Check offer (of struct GNUNET_HashCodes).

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

Definition at line 2045 of file gnunet-service-set_union.c.

2047 {
2048  struct Operation *op = cls;
2049  unsigned int num_hashes;
2050 
2051  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
2052  {
2053  GNUNET_break_op (0);
2054  return GNUNET_SYSERR;
2055  }
2056  /* look up elements and send them */
2057  if ((op->state->phase != PHASE_INVENTORY_PASSIVE) &&
2058  (op->state->phase != PHASE_INVENTORY_ACTIVE))
2059  {
2060  GNUNET_break_op (0);
2061  return GNUNET_SYSERR;
2062  }
2063  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2064  / sizeof(struct GNUNET_HashCode);
2065  if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader)) !=
2066  num_hashes * sizeof(struct GNUNET_HashCode))
2067  {
2068  GNUNET_break_op (0);
2069  return GNUNET_SYSERR;
2070  }
2071  return GNUNET_OK;
2072 }

References GNUNET_break_op, GNUNET_OK, GNUNET_SET_OPERATION_UNION, GNUNET_SYSERR, mh, op, PHASE_INVENTORY_ACTIVE, and PHASE_INVENTORY_PASSIVE.

◆ handle_union_p2p_offer()

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

Parameters
clsthe union operation
mhthe message

Definition at line 2083 of file gnunet-service-set_union.c.

2085 {
2086  struct Operation *op = cls;
2087  const struct GNUNET_HashCode *hash;
2088  unsigned int num_hashes;
2089 
2090  num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2091  / sizeof(struct GNUNET_HashCode);
2092  for (hash = (const struct GNUNET_HashCode *) &mh[1];
2093  num_hashes > 0;
2094  hash++, num_hashes--)
2095  {
2096  struct ElementEntry *ee;
2097  struct GNUNET_MessageHeader *demands;
2098  struct GNUNET_MQ_Envelope *ev;
2099 
2100  ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
2101  hash);
2102  if (NULL != ee)
2104  continue;
2105 
2106  if (GNUNET_YES ==
2107  GNUNET_CONTAINER_multihashmap_contains (op->state->demanded_hashes,
2108  hash))
2109  {
2111  "Skipped sending duplicate demand\n");
2112  continue;
2113  }
2114 
2117  op->state->demanded_hashes,
2118  hash,
2119  NULL,
2121 
2123  "[OP %p] Requesting element (hash %s)\n",
2124  op, GNUNET_h2s (hash));
2125  ev = GNUNET_MQ_msg_header_extra (demands,
2126  sizeof(struct GNUNET_HashCode),
2128  GNUNET_memcpy (&demands[1],
2129  hash,
2130  sizeof(struct GNUNET_HashCode));
2131  GNUNET_MQ_send (op->mq, ev);
2132  }
2133  GNUNET_CADET_receive_done (op->channel);
2134 }
enum GNUNET_GenericReturnValue 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).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#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:99
#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND
Demand the whole element from the other peer, given only the hash code.

References _GSS_is_element_of_operation(), 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_SET_UNION_P2P_DEMAND, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), GNUNET_OK, GNUNET_YES, LOG, mh, and op.

Here is the call graph for this function:

◆ handle_union_p2p_done()

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

Handle a done message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2144 of file gnunet-service-set_union.c.

2146 {
2147  struct Operation *op = cls;
2148 
2149  if (GNUNET_SET_OPERATION_UNION != op->set->operation)
2150  {
2151  GNUNET_break_op (0);
2153  return;
2154  }
2155  switch (op->state->phase)
2156  {
2158  /* We got all requests, but still have to send our elements in response. */
2159  op->state->phase = PHASE_FINISH_WAITING;
2160 
2162  "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2163  /* The active peer is done sending offers
2164  * and inquiries. This means that all
2165  * our responses to that (demands and offers)
2166  * must be in flight (queued or in mesh).
2167  *
2168  * We should notify the active peer once
2169  * all our demands are satisfied, so that the active
2170  * peer can quit if we gave it everything.
2171  */GNUNET_CADET_receive_done (op->channel);
2172  maybe_finish (op);
2173  return;
2174 
2177  "got DONE (as active partner), waiting to finish\n");
2178  /* All demands of the other peer are satisfied,
2179  * and we processed all offers, thus we know
2180  * exactly what our demands must be.
2181  *
2182  * We'll close the channel
2183  * to the other peer once our demands are met.
2184  */op->state->phase = PHASE_FINISH_CLOSING;
2185  GNUNET_CADET_receive_done (op->channel);
2186  maybe_finish (op);
2187  return;
2188 
2189  default:
2190  GNUNET_break_op (0);
2192  return;
2193  }
2194 }
@ PHASE_FINISH_CLOSING
The protocol is almost finished, but we still have to flush our message queue and/or expect some elem...
@ PHASE_FINISH_WAITING
In the penultimate phase, we wait until all our demands are satisfied.

References fail_union_operation(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SET_OPERATION_UNION, LOG, maybe_finish(), op, PHASE_FINISH_CLOSING, PHASE_FINISH_WAITING, PHASE_INVENTORY_ACTIVE, and PHASE_INVENTORY_PASSIVE.

Here is the call graph for this function:

◆ handle_union_p2p_over()

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

Handle an over message from a remote peer.

Parameters
clsthe union operation
mhthe message

Definition at line 2198 of file gnunet-service-set_union.c.

2200 {
2201  send_client_done (cls);
2202 }

References send_client_done().

Here is the call graph for this function: