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

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

828{
829 struct Operation *op = cls;
830 int is_compressed;
831 size_t len;
832
833 if (op->state->phase != PHASE_EXPECT_SE)
834 {
835 GNUNET_break (0);
836 return GNUNET_SYSERR;
837 }
838 is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons (
839 msg->header.type));
840 len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
841 if ((GNUNET_NO == is_compressed) &&
843 {
844 GNUNET_break (0);
845 return GNUNET_SYSERR;
846 }
847 return GNUNET_OK;
848}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
#define IBF_BUCKET_SIZE
Size of one ibf bucket in bytes.
Definition ibf.h:72
static struct GNUNET_ARM_Operation * op
Current operation.
Definition gnunet-arm.c:143
#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.
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.
@ 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.
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, 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 858 of file gnunet-service-set_union.c.

860{
861 struct Operation *op = cls;
862 struct StrataEstimator *remote_se;
863 unsigned int diff;
864 uint64_t other_size;
865 size_t len;
866 int is_compressed;
867
868 is_compressed = (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC == htons (
869 msg->header.type));
871 "# bytes of SE received",
872 ntohs (msg->header.size),
873 GNUNET_NO);
874 len = ntohs (msg->header.size) - sizeof(struct StrataEstimatorMessage);
875 other_size = GNUNET_ntohll (msg->set_size);
879 if (NULL == remote_se)
880 {
881 /* insufficient resources, fail */
883 return;
884 }
885 if (GNUNET_OK !=
887 len,
888 is_compressed,
889 remote_se))
890 {
891 /* decompression failed */
892 strata_estimator_destroy (remote_se);
894 return;
895 }
896 GNUNET_assert (NULL != op->state->se);
897 diff = strata_estimator_difference (remote_se,
898 op->state->se);
899
900 if (diff > 200)
901 diff = diff * 3 / 2;
902
903 strata_estimator_destroy (remote_se);
904 strata_estimator_destroy (op->state->se);
905 op->state->se = NULL;
907 "got se diff=%d, using ibf size %d\n",
908 diff,
909 1U << get_order_from_difference (diff));
910
911 {
912 char *set_debug;
913
914 set_debug = getenv ("GNUNET_SET_BENCHMARK");
915 if ((NULL != set_debug) &&
916 (0 == strcmp (set_debug, "1")))
917 {
918 FILE *f = fopen ("set.log", "a");
919 fprintf (f, "%llu\n", (unsigned long long) diff);
920 fclose (f);
921 }
922 }
923
924 if ((GNUNET_YES == op->byzantine) &&
925 (other_size < op->byzantine_lower_bound))
926 {
927 GNUNET_break (0);
929 return;
930 }
931
932 if ((GNUNET_YES == op->force_full) ||
933 (diff > op->state->initial_size / 4) ||
934 (0 == other_size))
935 {
937 "Deciding to go for full set transmission (diff=%d, own set=%llu)\n",
938 diff,
939 (unsigned long long) op->state->initial_size);
941 "# of full sends",
942 1,
943 GNUNET_NO);
944 if ((op->state->initial_size <= other_size) ||
945 (0 == other_size))
946 {
948 }
949 else
950 {
951 struct GNUNET_MQ_Envelope *ev;
952
954 "Telling other peer that we expect its full set\n");
955 op->state->phase = PHASE_EXPECT_IBF;
958 GNUNET_MQ_send (op->mq,
959 ev);
960 }
961 }
962 else
963 {
965 "# of ibf sends",
966 1,
967 GNUNET_NO);
968 if (GNUNET_OK !=
969 send_ibf (op,
971 {
972 /* Internal error, best we can do is shut the connection */
974 "Failed to send IBF, closing connection\n");
976 return;
977 }
978 }
979 GNUNET_CADET_receive_done (op->channel);
980}
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)
Indicate readiness to receive the next message on a channel.
Definition cadet_api.c:875
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
@ 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:305
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
#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, 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, 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 1215 of file gnunet-service-set_union.c.

1217{
1218 struct Operation *op = cls;
1219 unsigned int buckets_in_message;
1220
1221 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1222 {
1223 GNUNET_break_op (0);
1224 return GNUNET_SYSERR;
1225 }
1226 buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1228 if (0 == buckets_in_message)
1229 {
1230 GNUNET_break_op (0);
1231 return GNUNET_SYSERR;
1232 }
1233 if ((ntohs (msg->header.size) - sizeof *msg) != buckets_in_message
1235 {
1236 GNUNET_break_op (0);
1237 return GNUNET_SYSERR;
1238 }
1239 if (op->state->phase == PHASE_EXPECT_IBF_CONT)
1240 {
1241 if (ntohl (msg->offset) != op->state->ibf_buckets_received)
1242 {
1243 GNUNET_break_op (0);
1244 return GNUNET_SYSERR;
1245 }
1246 if (1 << msg->order != op->state->remote_ibf->size)
1247 {
1248 GNUNET_break_op (0);
1249 return GNUNET_SYSERR;
1250 }
1251 if (ntohl (msg->salt) != op->state->salt_receive)
1252 {
1253 GNUNET_break_op (0);
1254 return GNUNET_SYSERR;
1255 }
1256 }
1257 else if ((op->state->phase != PHASE_INVENTORY_PASSIVE) &&
1258 (op->state->phase != PHASE_EXPECT_IBF))
1259 {
1260 GNUNET_break_op (0);
1261 return GNUNET_SYSERR;
1262 }
1263
1264 return GNUNET_OK;
1265}
@ 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 1278 of file gnunet-service-set_union.c.

1280{
1281 struct Operation *op = cls;
1282 unsigned int buckets_in_message;
1283
1284 buckets_in_message = (ntohs (msg->header.size) - sizeof *msg)
1286 if ((op->state->phase == PHASE_INVENTORY_PASSIVE) ||
1287 (op->state->phase == PHASE_EXPECT_IBF))
1288 {
1289 op->state->phase = PHASE_EXPECT_IBF_CONT;
1290 GNUNET_assert (NULL == op->state->remote_ibf);
1292 "Creating new ibf of size %u\n",
1293 1 << msg->order);
1294 op->state->remote_ibf = ibf_create (1 << msg->order, SE_IBF_HASH_NUM);
1295 op->state->salt_receive = ntohl (msg->salt);
1297 "Receiving new IBF with salt %u\n",
1298 op->state->salt_receive);
1299 if (NULL == op->state->remote_ibf)
1300 {
1302 "Failed to parse remote IBF, closing connection\n");
1304 return;
1305 }
1306 op->state->ibf_buckets_received = 0;
1307 if (0 != ntohl (msg->offset))
1308 {
1309 GNUNET_break_op (0);
1311 return;
1312 }
1313 }
1314 else
1315 {
1316 GNUNET_assert (op->state->phase == PHASE_EXPECT_IBF_CONT);
1318 "Received more of IBF\n");
1319 }
1320 GNUNET_assert (NULL != op->state->remote_ibf);
1321
1322 ibf_read_slice (&msg[1],
1323 op->state->ibf_buckets_received,
1324 buckets_in_message,
1325 op->state->remote_ibf);
1326 op->state->ibf_buckets_received += buckets_in_message;
1327
1328 if (op->state->ibf_buckets_received == op->state->remote_ibf->size)
1329 {
1331 "received full ibf\n");
1332 op->state->phase = PHASE_INVENTORY_ACTIVE;
1333 if (GNUNET_OK !=
1335 {
1336 /* Internal error, best we can do is shut down */
1338 "Failed to decode IBF, closing connection\n");
1340 return;
1341 }
1342 }
1343 GNUNET_CADET_receive_done (op->channel);
1344}
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
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.

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

1496{
1497 struct Operation *op = cls;
1498
1499 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1500 {
1501 GNUNET_break_op (0);
1502 return GNUNET_SYSERR;
1503 }
1504 if (0 == GNUNET_CONTAINER_multihashmap_size (op->state->demanded_hashes))
1505 {
1506 GNUNET_break_op (0);
1507 return GNUNET_SYSERR;
1508 }
1509 return GNUNET_OK;
1510}
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 1522 of file gnunet-service-set_union.c.

1524{
1525 struct Operation *op = cls;
1526 struct ElementEntry *ee;
1527 struct KeyEntry *ke;
1528 uint16_t element_size;
1529
1530 element_size = ntohs (emsg->header.size) - sizeof(struct
1532 ee = GNUNET_malloc (sizeof(struct ElementEntry) + element_size);
1533 GNUNET_memcpy (&ee[1],
1534 &emsg[1],
1535 element_size);
1536 ee->element.size = element_size;
1537 ee->element.data = &ee[1];
1538 ee->element.element_type = ntohs (emsg->element_type);
1539 ee->remote = GNUNET_YES;
1541 &ee->element_hash);
1542 if (GNUNET_NO ==
1543 GNUNET_CONTAINER_multihashmap_remove (op->state->demanded_hashes,
1544 &ee->element_hash,
1545 NULL))
1546 {
1547 /* We got something we didn't demand, since it's not in our map. */
1548 GNUNET_break_op (0);
1550 return;
1551 }
1552
1554 "Got element (size %u, hash %s) from peer\n",
1555 (unsigned int) element_size,
1556 GNUNET_h2s (&ee->element_hash));
1557
1559 "# received elements",
1560 1,
1561 GNUNET_NO);
1563 "# exchanged elements",
1564 1,
1565 GNUNET_NO);
1566
1567 op->state->received_total++;
1568
1569 ke = op_get_element (op, &ee->element_hash);
1570 if (NULL != ke)
1571 {
1572 /* Got repeated element. Should not happen since
1573 * we track demands. */
1575 "# repeated elements",
1576 1,
1577 GNUNET_NO);
1578 ke->received = GNUNET_YES;
1579 GNUNET_free (ee);
1580 }
1581 else
1582 {
1584 "Registering new element from remote peer\n");
1585 op->state->received_fresh++;
1587 /* only send results immediately if the client wants it */
1588 switch (op->result_mode)
1589 {
1592 break;
1593
1596 break;
1597
1598 default:
1599 /* Result mode not supported, should have been caught earlier. */
1600 GNUNET_break (0);
1601 break;
1602 }
1603 }
1604
1605 if ((op->state->received_total > 8) &&
1606 (op->state->received_fresh < op->state->received_total / 3))
1607 {
1608 /* The other peer gave us lots of old elements, there's something wrong. */
1609 GNUNET_break_op (0);
1611 return;
1612 }
1613 GNUNET_CADET_receive_done (op->channel);
1614 maybe_finish (op);
1615}
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 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 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.
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, GNUNET_SET_ElementMessage::element_type, GNUNET_SET_Element::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 1625 of file gnunet-service-set_union.c.

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

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

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

References _GSS_statistics, GNUNET_SET_Element::data, ElementEntry::element, ElementEntry::element_hash, GNUNET_SET_ElementMessage::element_type, GNUNET_SET_Element::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 1742 of file gnunet-service-set_union.c.

1744{
1745 struct Operation *op = cls;
1746 unsigned int num_keys;
1747
1748 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1749 {
1750 GNUNET_break_op (0);
1751 return GNUNET_SYSERR;
1752 }
1753 if (op->state->phase != PHASE_INVENTORY_PASSIVE)
1754 {
1755 GNUNET_break_op (0);
1756 return GNUNET_SYSERR;
1757 }
1758 num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
1759 / sizeof(struct IBF_Key);
1760 if ((ntohs (msg->header.size) - sizeof(struct InquiryMessage))
1761 != num_keys * sizeof(struct IBF_Key))
1762 {
1763 GNUNET_break_op (0);
1764 return GNUNET_SYSERR;
1765 }
1766 return GNUNET_OK;
1767}
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 1778 of file gnunet-service-set_union.c.

1780{
1781 struct Operation *op = cls;
1782 const struct IBF_Key *ibf_key;
1783 unsigned int num_keys;
1784
1786 "Received union inquiry\n");
1787 num_keys = (ntohs (msg->header.size) - sizeof(struct InquiryMessage))
1788 / sizeof(struct IBF_Key);
1789 ibf_key = (const struct IBF_Key *) &msg[1];
1790 while (0 != num_keys--)
1791 {
1792 struct IBF_Key unsalted_key;
1793
1794 unsalt_key (ibf_key,
1795 ntohl (msg->salt),
1796 &unsalted_key);
1798 unsalted_key);
1799 ibf_key++;
1800 }
1801 GNUNET_CADET_receive_done (op->channel);
1802}
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 1848 of file gnunet-service-set_union.c.

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

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

1884{
1885 struct Operation *op = cls;
1886
1887 switch (op->state->phase)
1888 {
1889 case PHASE_EXPECT_IBF:
1890 {
1891 struct GNUNET_MQ_Envelope *ev;
1892
1894 "got FULL DONE, sending elements that other peer is missing\n");
1895
1896 /* send all the elements that did not come from the remote peer */
1897 GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element,
1899 op);
1900
1902 GNUNET_MQ_send (op->mq,
1903 ev);
1904 op->state->phase = PHASE_DONE;
1905 /* we now wait until the other peer sends us the OVER message*/
1906 }
1907 break;
1908
1909 case PHASE_FULL_SENDING:
1910 {
1912 "got FULL DONE, finishing\n");
1913 /* We sent the full set, and got the response for that. We're done. */
1914 op->state->phase = PHASE_DONE;
1915 GNUNET_CADET_receive_done (op->channel);
1918 return;
1919 }
1920 break;
1921
1922 default:
1924 "Handle full done phase is %u\n",
1925 (unsigned) op->state->phase);
1926 GNUNET_break_op (0);
1928 return;
1929 }
1930 GNUNET_CADET_receive_done (op->channel);
1931}
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 1943 of file gnunet-service-set_union.c.

1945{
1946 struct Operation *op = cls;
1947 unsigned int num_hashes;
1948
1949 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1950 {
1951 GNUNET_break_op (0);
1952 return GNUNET_SYSERR;
1953 }
1954 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
1955 / sizeof(struct GNUNET_HashCode);
1956 if ((ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
1957 != num_hashes * sizeof(struct GNUNET_HashCode))
1958 {
1959 GNUNET_break_op (0);
1960 return GNUNET_SYSERR;
1961 }
1962 return GNUNET_OK;
1963}
static struct GNUNET_CADET_Handle * mh
Cadet handle.
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 1974 of file gnunet-service-set_union.c.

1976{
1977 struct Operation *op = cls;
1978 struct ElementEntry *ee;
1979 struct GNUNET_SET_ElementMessage *emsg;
1980 const struct GNUNET_HashCode *hash;
1981 unsigned int num_hashes;
1982 struct GNUNET_MQ_Envelope *ev;
1983
1984 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
1985 / sizeof(struct GNUNET_HashCode);
1986 for (hash = (const struct GNUNET_HashCode *) &mh[1];
1987 num_hashes > 0;
1988 hash++, num_hashes--)
1989 {
1990 ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
1991 hash);
1992 if (NULL == ee)
1993 {
1994 /* Demand for non-existing element. */
1995 GNUNET_break_op (0);
1997 return;
1998 }
2000 {
2001 /* Probably confused lazily copied sets. */
2002 GNUNET_break_op (0);
2004 return;
2005 }
2006 ev = GNUNET_MQ_msg_extra (emsg, ee->element.size,
2008 GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size);
2009 emsg->reserved = htons (0);
2010 emsg->element_type = htons (ee->element.element_type);
2012 "[OP %p] Sending demanded element (size %u, hash %s) to peer\n",
2013 op,
2014 (unsigned int) ee->element.size,
2015 GNUNET_h2s (&ee->element_hash));
2016 GNUNET_MQ_send (op->mq, ev);
2018 "# exchanged elements",
2019 1,
2020 GNUNET_NO);
2021
2022 switch (op->result_mode)
2023 {
2025 /* Nothing to do. */
2026 break;
2027
2030 break;
2031
2032 default:
2033 /* Result mode not supported, should have been caught earlier. */
2034 GNUNET_break (0);
2035 break;
2036 }
2037 }
2038 GNUNET_CADET_receive_done (op->channel);
2039}
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.
#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_ElementMessage::element_type, GNUNET_SET_Element::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 2050 of file gnunet-service-set_union.c.

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

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

2090{
2091 struct Operation *op = cls;
2092 const struct GNUNET_HashCode *hash;
2093 unsigned int num_hashes;
2094
2095 num_hashes = (ntohs (mh->size) - sizeof(struct GNUNET_MessageHeader))
2096 / sizeof(struct GNUNET_HashCode);
2097 for (hash = (const struct GNUNET_HashCode *) &mh[1];
2098 num_hashes > 0;
2099 hash++, num_hashes--)
2100 {
2101 struct ElementEntry *ee;
2102 struct GNUNET_MessageHeader *demands;
2103 struct GNUNET_MQ_Envelope *ev;
2104
2105 ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
2106 hash);
2107 if (NULL != ee)
2109 continue;
2110
2111 if (GNUNET_YES ==
2112 GNUNET_CONTAINER_multihashmap_contains (op->state->demanded_hashes,
2113 hash))
2114 {
2116 "Skipped sending duplicate demand\n");
2117 continue;
2118 }
2119
2122 op->state->demanded_hashes,
2123 hash,
2124 NULL,
2126
2128 "[OP %p] Requesting element (hash %s)\n",
2129 op, GNUNET_h2s (hash));
2130 ev = GNUNET_MQ_msg_header_extra (demands,
2131 sizeof(struct GNUNET_HashCode),
2133 GNUNET_memcpy (&demands[1],
2134 hash,
2135 sizeof(struct GNUNET_HashCode));
2136 GNUNET_MQ_send (op->mq, ev);
2137 }
2138 GNUNET_CADET_receive_done (op->channel);
2139}
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.
#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 2149 of file gnunet-service-set_union.c.

2151{
2152 struct Operation *op = cls;
2153
2154 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
2155 {
2156 GNUNET_break_op (0);
2158 return;
2159 }
2160 switch (op->state->phase)
2161 {
2163 /* We got all requests, but still have to send our elements in response. */
2164 op->state->phase = PHASE_FINISH_WAITING;
2165
2167 "got DONE (as passive partner), waiting for our demands to be satisfied\n");
2168 /* The active peer is done sending offers
2169 * and inquiries. This means that all
2170 * our responses to that (demands and offers)
2171 * must be in flight (queued or in mesh).
2172 *
2173 * We should notify the active peer once
2174 * all our demands are satisfied, so that the active
2175 * peer can quit if we gave it everything.
2176 */GNUNET_CADET_receive_done (op->channel);
2177 maybe_finish (op);
2178 return;
2179
2182 "got DONE (as active partner), waiting to finish\n");
2183 /* All demands of the other peer are satisfied,
2184 * and we processed all offers, thus we know
2185 * exactly what our demands must be.
2186 *
2187 * We'll close the channel
2188 * to the other peer once our demands are met.
2189 */op->state->phase = PHASE_FINISH_CLOSING;
2190 GNUNET_CADET_receive_done (op->channel);
2191 maybe_finish (op);
2192 return;
2193
2194 default:
2195 GNUNET_break_op (0);
2197 return;
2198 }
2199}
@ 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 2203 of file gnunet-service-set_union.c.

2205{
2206 send_client_done (cls);
2207}

References send_client_done().

Here is the call graph for this function: