From ed07d0c162984ddedc9399744e7736a101d3df2b Mon Sep 17 00:00:00 2001 From: Julius Bünger Date: Thu, 4 Oct 2018 10:25:52 +0200 Subject: Restructure service towards having subsamplers --- src/rps/gnunet-service-rps.c | 1025 ++++++++++++++++++++++++------------------ src/rps/rps-test_util.h | 4 +- 2 files changed, 585 insertions(+), 444 deletions(-) diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 07b88ddcd..d1c169239 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c @@ -148,6 +148,11 @@ struct ChannelCtx; */ struct PeerContext { + /** + * The SubSampler this context belongs to. + */ + struct SubSampler *ss; + /** * Message queue open to client */ @@ -533,19 +538,21 @@ static const uint32_t num_valid_peers_max = UINT32_MAX; /** * @brief Get the #PeerContext associated with a peer * + * @param peer_map The peer map containing the context * @param peer the peer id * * @return the #PeerContext */ static struct PeerContext * -get_peer_ctx (const struct GNUNET_PeerIdentity *peer) +get_peer_ctx (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, + const struct GNUNET_PeerIdentity *peer) { struct PeerContext *ctx; int ret; - ret = GNUNET_CONTAINER_multipeermap_contains (mss->peer_map, peer); + ret = GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); GNUNET_assert (GNUNET_YES == ret); - ctx = GNUNET_CONTAINER_multipeermap_get (mss->peer_map, peer); + ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer); GNUNET_assert (NULL != ctx); return ctx; } @@ -555,18 +562,21 @@ get_peer_ctx (const struct GNUNET_PeerIdentity *peer) * * FIXME probably deprecated. Make this the new _online. * + * @param peer_map The peer map to check for the existence of @a peer * @param peer peer in question * * @return #GNUNET_YES if peer is known * #GNUNET_NO if peer is not knwon */ static int -check_peer_known (const struct GNUNET_PeerIdentity *peer) +check_peer_known (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, + const struct GNUNET_PeerIdentity *peer) { - if (NULL != mss->peer_map) + if (NULL != peer_map) { - return GNUNET_CONTAINER_multipeermap_contains (mss->peer_map, peer); - } else + return GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); + } + else { return GNUNET_NO; } @@ -576,26 +586,29 @@ check_peer_known (const struct GNUNET_PeerIdentity *peer) /** * @brief Create a new #PeerContext and insert it into the peer map * + * @param ss The SubSampler this context belongs to. * @param peer the peer to create the #PeerContext for * * @return the #PeerContext */ static struct PeerContext * -create_peer_ctx (const struct GNUNET_PeerIdentity *peer) +create_peer_ctx (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { struct PeerContext *ctx; int ret; - GNUNET_assert (GNUNET_NO == check_peer_known (peer)); + GNUNET_assert (GNUNET_NO == check_peer_known (ss->peer_map, peer)); ctx = GNUNET_new (struct PeerContext); ctx->peer_id = *peer; - ret = GNUNET_CONTAINER_multipeermap_put (mss->peer_map, peer, ctx, + ctx->ss = ss; + ret = GNUNET_CONTAINER_multipeermap_put (ss->peer_map, peer, ctx, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); GNUNET_assert (GNUNET_OK == ret); GNUNET_STATISTICS_set (stats, "# known peers", - GNUNET_CONTAINER_multipeermap_size (mss->peer_map), + GNUNET_CONTAINER_multipeermap_size (ss->peer_map), GNUNET_NO); return ctx; } @@ -604,18 +617,20 @@ create_peer_ctx (const struct GNUNET_PeerIdentity *peer) /** * @brief Create or get a #PeerContext * + * @param ss The SubSampler to which the created context belongs to * @param peer the peer to get the associated context to * * @return the context */ static struct PeerContext * -create_or_get_peer_ctx (const struct GNUNET_PeerIdentity *peer) +create_or_get_peer_ctx (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { - if (GNUNET_NO == check_peer_known (peer)) + if (GNUNET_NO == check_peer_known (ss->peer_map, peer)) { - return create_peer_ctx (peer); + return create_peer_ctx (ss, peer); } - return get_peer_ctx (peer); + return get_peer_ctx (ss->peer_map, peer); } @@ -624,23 +639,22 @@ create_or_get_peer_ctx (const struct GNUNET_PeerIdentity *peer) * * Also sets the #Peers_ONLINE flag accordingly * - * @param peer the peer in question + * @param peer_ctx Context of the peer of which connectivity is to be checked * * @return #GNUNET_YES if we are connected * #GNUNET_NO otherwise */ static int -check_connected (const struct GNUNET_PeerIdentity *peer) +check_connected (struct PeerContext *peer_ctx) { - struct PeerContext *peer_ctx; - /* If we don't know about this peer we don't know whether it's online */ - if (GNUNET_NO == check_peer_known (peer)) + if (GNUNET_NO == check_peer_known (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)) { return GNUNET_NO; } /* Get the context */ - peer_ctx = get_peer_ctx (peer); + peer_ctx = get_peer_ctx (peer_ctx->ss->peer_map, &peer_ctx->peer_id); /* If we have no channel to this peer we don't know whether it's online */ if ( (NULL == peer_ctx->send_channel_ctx) && (NULL == peer_ctx->recv_channel_ctx) ) @@ -709,21 +723,22 @@ get_rand_peer_iterator (void *cls, /** * @brief Get a random peer from @a peer_map * - * @param peer_map the peer_map to get the peer from + * @param valid_peers Peer map containing valid peers from which to select a + * random one * * @return a random peer */ static const struct GNUNET_PeerIdentity * get_random_peer_from_peermap (const struct - GNUNET_CONTAINER_MultiPeerMap *peer_map) + GNUNET_CONTAINER_MultiPeerMap *valid_peers) { struct GetRandPeerIteratorCls *iterator_cls; const struct GNUNET_PeerIdentity *ret; iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls); iterator_cls->index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, - GNUNET_CONTAINER_multipeermap_size (peer_map)); - (void) GNUNET_CONTAINER_multipeermap_iterate (mss->valid_peers, + GNUNET_CONTAINER_multipeermap_size (valid_peers)); + (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers, get_rand_peer_iterator, iterator_cls); ret = iterator_cls->peer; @@ -737,30 +752,33 @@ get_random_peer_from_peermap (const struct * * If valid peers are already #num_valid_peers_max, delete a peer previously. * - * @param peer the peer that is added to the valid peers. + * @param peer The peer that is added to the valid peers. + * @param valid_peers Peer map of valid peers to which to add the @a peer * * @return #GNUNET_YES if no other peer had to be removed * #GNUNET_NO otherwise */ static int -add_valid_peer (const struct GNUNET_PeerIdentity *peer) +add_valid_peer (const struct GNUNET_PeerIdentity *peer, + struct GNUNET_CONTAINER_MultiPeerMap *valid_peers) { const struct GNUNET_PeerIdentity *rand_peer; int ret; ret = GNUNET_YES; - while (GNUNET_CONTAINER_multipeermap_size ( - mss->valid_peers) >= num_valid_peers_max) + /* Remove random peers until there is space for a new one */ + while (num_valid_peers_max <= + GNUNET_CONTAINER_multipeermap_size (valid_peers)) { - rand_peer = get_random_peer_from_peermap (mss->valid_peers); - GNUNET_CONTAINER_multipeermap_remove_all (mss->valid_peers, rand_peer); + rand_peer = get_random_peer_from_peermap (valid_peers); + GNUNET_CONTAINER_multipeermap_remove_all (valid_peers, rand_peer); ret = GNUNET_NO; } - (void) GNUNET_CONTAINER_multipeermap_put (mss->valid_peers, peer, NULL, + (void) GNUNET_CONTAINER_multipeermap_put (valid_peers, peer, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); GNUNET_STATISTICS_set (stats, "# valid peers", - GNUNET_CONTAINER_multipeermap_size (mss->valid_peers), + GNUNET_CONTAINER_multipeermap_size (valid_peers), GNUNET_NO); return ret; } @@ -799,7 +817,6 @@ set_peer_online (struct PeerContext *peer_ctx) peer_ctx->online_check_pending = NULL; } - (void) add_valid_peer (peer); SET_PEER_FLAG (peer_ctx, Peers_ONLINE); /* Call pending operations */ @@ -888,13 +905,12 @@ remove_channel_ctx (struct ChannelCtx *channel_ctx) /** * @brief Get the channel of a peer. If not existing, create. * - * @param peer the peer id - * @return the #GNUNET_CADET_Channel used to send data to @a peer + * @param peer_ctx Context of the peer of which to get the channel + * @return the #GNUNET_CADET_Channel used to send data to @a peer_ctx */ struct GNUNET_CADET_Channel * -get_channel (const struct GNUNET_PeerIdentity *peer) +get_channel (struct PeerContext *peer_ctx) { - struct PeerContext *peer_ctx; struct GNUNET_PeerIdentity *ctx_peer; /* There exists a copy-paste-clone in run() */ struct GNUNET_MQ_MessageHandler cadet_handlers[] = { @@ -918,20 +934,19 @@ get_channel (const struct GNUNET_PeerIdentity *peer) }; - peer_ctx = get_peer_ctx (peer); if (NULL == peer_ctx->send_channel_ctx) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to establish channel to peer %s\n", - GNUNET_i2s (peer)); + GNUNET_i2s (&peer_ctx->peer_id)); ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); - *ctx_peer = *peer; + *ctx_peer = peer_ctx->peer_id; peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx); peer_ctx->send_channel_ctx->channel = - GNUNET_CADET_channel_create (mss->cadet_handle, + GNUNET_CADET_channel_create (peer_ctx->ss->cadet_handle, peer_ctx->send_channel_ctx, /* context */ - peer, - &mss->port, + &peer_ctx->peer_id, + &peer_ctx->ss->port, GNUNET_CADET_OPTION_RELIABLE, NULL, /* WindowSize handler */ &cleanup_destroyed_channel, /* Disconnect handler */ @@ -949,19 +964,15 @@ get_channel (const struct GNUNET_PeerIdentity *peer) * If we already have a message queue open to this client, * simply return it, otherways create one. * - * @param peer the peer to get the mq to + * @param peer_ctx Context of the peer of whicht to get the mq * @return the #GNUNET_MQ_Handle */ static struct GNUNET_MQ_Handle * -get_mq (const struct GNUNET_PeerIdentity *peer) +get_mq (struct PeerContext *peer_ctx) { - struct PeerContext *peer_ctx; - - peer_ctx = get_peer_ctx (peer); - if (NULL == peer_ctx->mq) { - peer_ctx->mq = GNUNET_CADET_get_mq (get_channel (peer)); + peer_ctx->mq = GNUNET_CADET_get_mq (get_channel (peer_ctx)); } return peer_ctx->mq; } @@ -969,20 +980,18 @@ get_mq (const struct GNUNET_PeerIdentity *peer) /** * @brief Add an envelope to a message passed to mq to list of pending messages * - * @param peer peer the message was sent to + * @param peer_ctx Context of the peer for which to insert the envelope * @param ev envelope to the message * @param type type of the message to be sent * @return pointer to pending message */ static struct PendingMessage * -insert_pending_message (const struct GNUNET_PeerIdentity *peer, +insert_pending_message (struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type) { struct PendingMessage *pending_msg; - struct PeerContext *peer_ctx; - peer_ctx = get_peer_ctx (peer); pending_msg = GNUNET_new (struct PendingMessage); pending_msg->ev = ev; pending_msg->peer_ctx = peer_ctx; @@ -1039,6 +1048,7 @@ mq_online_check_successful (void *cls) remove_pending_message (peer_ctx->online_check_pending, GNUNET_YES); peer_ctx->online_check_pending = NULL; set_peer_online (peer_ctx); + (void) add_valid_peer (&peer_ctx->peer_id, peer_ctx->ss->valid_peers); } } @@ -1059,8 +1069,8 @@ check_peer_online (struct PeerContext *peer_ctx) ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE); peer_ctx->online_check_pending = - insert_pending_message (&peer_ctx->peer_id, ev, "Check online"); - mq = get_mq (&peer_ctx->peer_id); + insert_pending_message (peer_ctx, ev, "Check online"); + mq = get_mq (peer_ctx); GNUNET_MQ_notify_sent (ev, mq_online_check_successful, peer_ctx); @@ -1078,20 +1088,18 @@ check_peer_online (struct PeerContext *peer_ctx) * The array with pending operations will probably never grow really big, so * iterating over it should be ok. * - * @param peer the peer to check + * @param peer_ctx Context of the peer to check for the operation * @param peer_op the operation (#PeerOp) on the peer * * @return #GNUNET_YES if this operation is scheduled on that peer * #GNUNET_NO otherwise */ static int -check_operation_scheduled (const struct GNUNET_PeerIdentity *peer, +check_operation_scheduled (const struct PeerContext *peer_ctx, const PeerOp peer_op) { - const struct PeerContext *peer_ctx; unsigned int i; - peer_ctx = get_peer_ctx (peer); for (i = 0; i < peer_ctx->num_pending_ops; i++) if (peer_op == peer_ctx->pending_ops[i].op) return GNUNET_YES; @@ -1165,7 +1173,13 @@ schedule_channel_destruction (struct ChannelCtx *channel_ctx) /** * @brief Remove peer * - * @param peer the peer to clean + * - Empties the list with pending operations + * - Empties the list with pending messages + * - Cancels potentially existing online check + * - Schedules closing of send and recv channels + * - Removes peer from peer map + * + * @param peer_ctx Context of the peer to be destroyed * @return #GNUNET_YES if peer was removed * #GNUNET_NO otherwise */ @@ -1173,9 +1187,9 @@ static int destroy_peer (struct PeerContext *peer_ctx) { GNUNET_assert (NULL != peer_ctx); - GNUNET_assert (NULL != mss->peer_map); + GNUNET_assert (NULL != peer_ctx->ss->peer_map); if (GNUNET_NO == - GNUNET_CONTAINER_multipeermap_contains (mss->peer_map, + GNUNET_CONTAINER_multipeermap_contains (peer_ctx->ss->peer_map, &peer_ctx->peer_id)) { return GNUNET_NO; @@ -1245,15 +1259,15 @@ destroy_peer (struct PeerContext *peer_ctx) } if (GNUNET_YES != - GNUNET_CONTAINER_multipeermap_remove_all (mss->peer_map, + GNUNET_CONTAINER_multipeermap_remove_all (peer_ctx->ss->peer_map, &peer_ctx->peer_id)) { LOG (GNUNET_ERROR_TYPE_WARNING, - "removing peer from mss->peer_map failed\n"); + "removing peer from peer_ctx->ss->peer_map failed\n"); } GNUNET_STATISTICS_set (stats, "# known peers", - GNUNET_CONTAINER_multipeermap_size (mss->peer_map), + GNUNET_CONTAINER_multipeermap_size (peer_ctx->ss->peer_map), GNUNET_NO); GNUNET_free (peer_ctx); return GNUNET_YES; @@ -1274,9 +1288,10 @@ peermap_clear_iterator (void *cls, const struct GNUNET_PeerIdentity *key, void *value) { - (void) cls; + struct SubSampler *ss = cls; (void) value; - destroy_peer (get_peer_ctx (key)); + + destroy_peer (get_peer_ctx (ss->peer_map, key)); return GNUNET_YES; } @@ -1350,35 +1365,37 @@ store_peer_presistently_iterator (void *cls, /** * @brief Store the peers currently in #valid_peers to disk. + * + * @param ss SubSampler for which to store the valid peers */ static void -store_valid_peers () +store_valid_peers (const struct SubSampler *ss) { struct GNUNET_DISK_FileHandle *fh; uint32_t number_written_peers; int ret; - if (0 == strncmp ("DISABLE", mss->filename_valid_peers, 7)) + if (0 == strncmp ("DISABLE", ss->filename_valid_peers, 7)) { return; } - ret = GNUNET_DISK_directory_create_for_file (mss->filename_valid_peers); + ret = GNUNET_DISK_directory_create_for_file (ss->filename_valid_peers); if (GNUNET_SYSERR == ret) { LOG (GNUNET_ERROR_TYPE_WARNING, "Not able to create directory for file `%s'\n", - mss->filename_valid_peers); + ss->filename_valid_peers); GNUNET_break (0); } else if (GNUNET_NO == ret) { LOG (GNUNET_ERROR_TYPE_WARNING, "Directory for file `%s' exists but is not writable for us\n", - mss->filename_valid_peers); + ss->filename_valid_peers); GNUNET_break (0); } - fh = GNUNET_DISK_file_open (mss->filename_valid_peers, + fh = GNUNET_DISK_file_open (ss->filename_valid_peers, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | @@ -1387,19 +1404,19 @@ store_valid_peers () { LOG (GNUNET_ERROR_TYPE_WARNING, "Not able to write valid peers to file `%s'\n", - mss->filename_valid_peers); + ss->filename_valid_peers); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing %u valid peers to disk\n", - GNUNET_CONTAINER_multipeermap_size (mss->valid_peers)); + GNUNET_CONTAINER_multipeermap_size (ss->valid_peers)); number_written_peers = - GNUNET_CONTAINER_multipeermap_iterate (mss->valid_peers, + GNUNET_CONTAINER_multipeermap_iterate (ss->valid_peers, store_peer_presistently_iterator, fh); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); GNUNET_assert (number_written_peers == - GNUNET_CONTAINER_multipeermap_size (mss->valid_peers)); + GNUNET_CONTAINER_multipeermap_size (ss->valid_peers)); } @@ -1451,9 +1468,11 @@ s2i_full (const char *string_repr) /** * @brief Restore the peers on disk to #valid_peers. + * + * @param ss SubSampler for which to restore the valid peers */ static void -restore_valid_peers () +restore_valid_peers (const struct SubSampler *ss) { off_t file_size; uint32_t num_peers; @@ -1464,16 +1483,16 @@ restore_valid_peers () char *str_repr; const struct GNUNET_PeerIdentity *peer; - if (0 == strncmp ("DISABLE", mss->filename_valid_peers, 7)) + if (0 == strncmp ("DISABLE", ss->filename_valid_peers, 7)) { return; } - if (GNUNET_OK != GNUNET_DISK_file_test (mss->filename_valid_peers)) + if (GNUNET_OK != GNUNET_DISK_file_test (ss->filename_valid_peers)) { return; } - fh = GNUNET_DISK_file_open (mss->filename_valid_peers, + fh = GNUNET_DISK_file_open (ss->filename_valid_peers, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); GNUNET_assert (NULL != fh); @@ -1485,13 +1504,13 @@ restore_valid_peers () LOG (GNUNET_ERROR_TYPE_DEBUG, "Restoring %" PRIu32 " peers from file `%s'\n", num_peers, - mss->filename_valid_peers); + ss->filename_valid_peers); for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53) { str_repr = GNUNET_strndup (iter_buf, 53); peer = s2i_full (str_repr); GNUNET_free (str_repr); - add_valid_peer (peer); + add_valid_peer (peer, ss->valid_peers); LOG (GNUNET_ERROR_TYPE_DEBUG, "Restored valid peer %s from disk\n", GNUNET_i2s_full (peer)); @@ -1499,10 +1518,10 @@ restore_valid_peers () iter_buf = NULL; GNUNET_free (buf); LOG (GNUNET_ERROR_TYPE_DEBUG, - "num_peers: %" PRIu32 ", _size (mss->valid_peers): %u\n", + "num_peers: %" PRIu32 ", _size (ss->valid_peers): %u\n", num_peers, - GNUNET_CONTAINER_multipeermap_size (mss->valid_peers)); - if (num_peers != GNUNET_CONTAINER_multipeermap_size (mss->valid_peers)) + GNUNET_CONTAINER_multipeermap_size (ss->valid_peers)); + if (num_peers != GNUNET_CONTAINER_multipeermap_size (ss->valid_peers)) { LOG (GNUNET_ERROR_TYPE_WARNING, "Number of restored peers does not match file size. Have probably duplicates.\n"); @@ -1510,38 +1529,40 @@ restore_valid_peers () GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Restored %u valid peers from disk\n", - GNUNET_CONTAINER_multipeermap_size (mss->valid_peers)); + GNUNET_CONTAINER_multipeermap_size (ss->valid_peers)); } /** * @brief Delete storage of peers that was created with #initialise_peers () + * + * @param ss SubSampler for which the storage is deleted */ static void -peers_terminate () +peers_terminate (struct SubSampler *ss) { if (GNUNET_SYSERR == - GNUNET_CONTAINER_multipeermap_iterate (mss->peer_map, + GNUNET_CONTAINER_multipeermap_iterate (ss->peer_map, &peermap_clear_iterator, - NULL)) + ss)) { LOG (GNUNET_ERROR_TYPE_WARNING, "Iteration destroying peers was aborted.\n"); } - GNUNET_CONTAINER_multipeermap_destroy (mss->peer_map); - mss->peer_map = NULL; - store_valid_peers (); - GNUNET_free (mss->filename_valid_peers); - mss->filename_valid_peers = NULL; - GNUNET_CONTAINER_multipeermap_destroy (mss->valid_peers); - mss->valid_peers = NULL; + GNUNET_CONTAINER_multipeermap_destroy (ss->peer_map); + ss->peer_map = NULL; + store_valid_peers (ss); + GNUNET_free (ss->filename_valid_peers); + ss->filename_valid_peers = NULL; + GNUNET_CONTAINER_multipeermap_destroy (ss->valid_peers); + ss->valid_peers = NULL; } /** * Iterator over #valid_peers hash map entries. * - * @param cls closure - unused + * @param cls Closure that contains iterator function and closure * @param peer current peer id * @param value value in the hash map - unused * @return #GNUNET_YES if we should continue to @@ -1556,21 +1577,22 @@ valid_peer_iterator (void *cls, struct PeersIteratorCls *it_cls = cls; (void) value; - return it_cls->iterator (it_cls->cls, - peer); + return it_cls->iterator (it_cls->cls, peer); } /** * @brief Get all currently known, valid peer ids. * - * @param it function to call on each peer id - * @param it_cls extra argument to @a it + * @param valid_peers Peer map containing the valid peers in question + * @param iterator function to call on each peer id + * @param it_cls extra argument to @a iterator * @return the number of key value pairs processed, * #GNUNET_SYSERR if it aborted iteration */ static int -get_valid_peers (PeersIterator iterator, +get_valid_peers (const struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, + PeersIterator iterator, void *it_cls) { struct PeersIteratorCls *cls; @@ -1579,7 +1601,7 @@ get_valid_peers (PeersIterator iterator, cls = GNUNET_new (struct PeersIteratorCls); cls->iterator = iterator; cls->cls = it_cls; - ret = GNUNET_CONTAINER_multipeermap_iterate (mss->valid_peers, + ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers, valid_peer_iterator, cls); GNUNET_free (cls); @@ -1593,19 +1615,21 @@ get_valid_peers (PeersIterator iterator, * This function is called on new peer_ids from 'external' sources * (client seed, cadet get_peers(), ...) * + * @param ss SubSampler with the peer map that the @a peer will be added to * @param peer the new #GNUNET_PeerIdentity * * @return #GNUNET_YES if peer was inserted * #GNUNET_NO otherwise */ static int -insert_peer (const struct GNUNET_PeerIdentity *peer) +insert_peer (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { - if (GNUNET_YES == check_peer_known (peer)) + if (GNUNET_YES == check_peer_known (ss->peer_map, peer)) { return GNUNET_NO; /* We already know this peer - nothing to do */ } - (void) create_peer_ctx (peer); + (void) create_peer_ctx (ss, peer); return GNUNET_YES; } @@ -1613,6 +1637,7 @@ insert_peer (const struct GNUNET_PeerIdentity *peer) /** * @brief Check whether flags on a peer are set. * + * @param peer_map Peer map that is expected to contain the @a peer * @param peer the peer to check the flag of * @param flags the flags to check * @@ -1621,16 +1646,17 @@ insert_peer (const struct GNUNET_PeerIdentity *peer) * #GNUNET_NO otherwise */ static int -check_peer_flag (const struct GNUNET_PeerIdentity *peer, +check_peer_flag (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, + const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags) { struct PeerContext *peer_ctx; - if (GNUNET_NO == check_peer_known (peer)) + if (GNUNET_NO == check_peer_known (peer_map, peer)) { return GNUNET_SYSERR; } - peer_ctx = get_peer_ctx (peer); + peer_ctx = get_peer_ctx (peer_map, peer); return check_peer_flag_set (peer_ctx, flags); } @@ -1639,18 +1665,20 @@ check_peer_flag (const struct GNUNET_PeerIdentity *peer, * * If not known yet, insert into known peers * + * @param ss SubSampler which would contain the @a peer * @param peer the peer whose online is to be checked * @return #GNUNET_YES if the check was issued * #GNUNET_NO otherwise */ static int -issue_peer_online_check (const struct GNUNET_PeerIdentity *peer) +issue_peer_online_check (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { struct PeerContext *peer_ctx; - (void) insert_peer (peer); - peer_ctx = get_peer_ctx (peer); - if ( (GNUNET_NO == check_peer_flag (peer, Peers_ONLINE)) && + (void) insert_peer (ss, peer); // TODO even needed? + peer_ctx = get_peer_ctx (ss->peer_map, peer); + if ( (GNUNET_NO == check_peer_flag (ss->peer_map, peer, Peers_ONLINE)) && (NULL == peer_ctx->online_check_pending) ) { check_peer_online (peer_ctx); @@ -1668,22 +1696,20 @@ issue_peer_online_check (const struct GNUNET_PeerIdentity *peer) * - there are pending messages * - there is no pending pull reply * - * @param peer the peer in question + * @param peer_ctx Context of the peer in question * @return #GNUNET_YES if peer is removable * #GNUNET_NO if peer is NOT removable * #GNUNET_SYSERR if peer is not known */ static int -check_removable (const struct GNUNET_PeerIdentity *peer) +check_removable (const struct PeerContext *peer_ctx) { - struct PeerContext *peer_ctx; - - if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mss->peer_map, peer)) + if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)) { return GNUNET_SYSERR; } - peer_ctx = get_peer_ctx (peer); if ( (NULL != peer_ctx->recv_channel_ctx) || (NULL != peer_ctx->pending_messages_head) || (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) @@ -1699,15 +1725,17 @@ check_removable (const struct GNUNET_PeerIdentity *peer) * * A valid peer is a peer that we know exists eg. we were connected to once. * + * @param valid_peers Peer map that would contain the @a peer * @param peer peer in question * * @return #GNUNET_YES if peer is valid * #GNUNET_NO if peer is not valid */ static int -check_peer_valid (const struct GNUNET_PeerIdentity *peer) +check_peer_valid (const struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, + const struct GNUNET_PeerIdentity *peer) { - return GNUNET_CONTAINER_multipeermap_contains (mss->valid_peers, peer); + return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer); } @@ -1716,13 +1744,14 @@ check_peer_valid (const struct GNUNET_PeerIdentity *peer) * * This establishes a sending channel * - * @param peer the peer to establish channel to + * @param peer_ctx Context of the target peer */ static void -indicate_sending_intention (const struct GNUNET_PeerIdentity *peer) +indicate_sending_intention (struct PeerContext *peer_ctx) { - GNUNET_assert (GNUNET_YES == check_peer_known (peer)); - (void) get_channel (peer); + GNUNET_assert (GNUNET_YES == check_peer_known (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)); + (void) get_channel (peer_ctx); } @@ -1730,17 +1759,14 @@ indicate_sending_intention (const struct GNUNET_PeerIdentity *peer) * @brief Check whether other peer has the intention to send/opened channel * towars us * - * @param peer the peer in question + * @param peer_ctx Context of the peer in question * * @return #GNUNET_YES if peer has the intention to send * #GNUNET_NO otherwise */ static int -check_peer_send_intention (const struct GNUNET_PeerIdentity *peer) +check_peer_send_intention (const struct PeerContext *peer_ctx) { - const struct PeerContext *peer_ctx; - - peer_ctx = get_peer_ctx (peer); if (NULL != peer_ctx->recv_channel_ctx) { return GNUNET_YES; @@ -1752,7 +1778,7 @@ check_peer_send_intention (const struct GNUNET_PeerIdentity *peer) /** * Handle the channel a peer opens to us. * - * @param cls The closure + * @param cls The closure - SubSampler * @param channel The channel the peer wants to establish * @param initiator The peer's peer ID * @@ -1767,21 +1793,23 @@ handle_inbound_channel (void *cls, struct PeerContext *peer_ctx; struct GNUNET_PeerIdentity *ctx_peer; struct ChannelCtx *channel_ctx; - (void) cls; + struct SubSampler *ss = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "New channel was established to us (Peer %s).\n", GNUNET_i2s (initiator)); GNUNET_assert (NULL != channel); /* according to cadet API */ /* Make sure we 'know' about this peer */ - peer_ctx = create_or_get_peer_ctx (initiator); + peer_ctx = create_or_get_peer_ctx (ss, initiator); set_peer_online (peer_ctx); + (void) add_valid_peer (&peer_ctx->peer_id, peer_ctx->ss->valid_peers); ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); *ctx_peer = *initiator; channel_ctx = add_channel_ctx (peer_ctx); channel_ctx->channel = channel; /* We only accept one incoming channel per peer */ - if (GNUNET_YES == check_peer_send_intention (initiator)) + if (GNUNET_YES == check_peer_send_intention (get_peer_ctx (ss->peer_map, + initiator))) { LOG (GNUNET_ERROR_TYPE_WARNING, "Already got one receive channel. Destroying old one.\n"); @@ -1799,21 +1827,19 @@ handle_inbound_channel (void *cls, /** * @brief Check whether a sending channel towards the given peer exists * - * @param peer the peer to check for + * @param peer_ctx Context of the peer in question * * @return #GNUNET_YES if a sending channel towards that peer exists * #GNUNET_NO otherwise */ static int -check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer) +check_sending_channel_exists (const struct PeerContext *peer_ctx) { - struct PeerContext *peer_ctx; - - if (GNUNET_NO == check_peer_known (peer)) + if (GNUNET_NO == check_peer_known (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)) { /* If no such peer exists, there is no channel */ return GNUNET_NO; } - peer_ctx = get_peer_ctx (peer); if (NULL == peer_ctx->send_channel_ctx) { return GNUNET_NO; @@ -1826,24 +1852,22 @@ check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer) * @brief Destroy the send channel of a peer e.g. stop indicating a sending * intention to another peer * - * @peer the peer identity of the peer whose sending channel to destroy + * @param peer_ctx Context to the peer * @return #GNUNET_YES if channel was destroyed * #GNUNET_NO otherwise */ static int -destroy_sending_channel (const struct GNUNET_PeerIdentity *peer) +destroy_sending_channel (struct PeerContext *peer_ctx) { - struct PeerContext *peer_ctx; - - if (GNUNET_NO == check_peer_known (peer)) + if (GNUNET_NO == check_peer_known (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)) { return GNUNET_NO; } - peer_ctx = get_peer_ctx (peer); if (NULL != peer_ctx->send_channel_ctx) { destroy_channel (peer_ctx->send_channel_ctx); - (void) check_connected (peer); + (void) check_connected (peer_ctx); return GNUNET_YES; } return GNUNET_NO; @@ -1855,12 +1879,12 @@ destroy_sending_channel (const struct GNUNET_PeerIdentity *peer) * Keeps track about pending messages so they can be properly removed when the * peer is destroyed. * - * @param peer receeiver of the message + * @param peer_ctx Context of the peer to which the message is to be sent * @param ev envelope of the message * @param type type of the message */ static void -send_message (const struct GNUNET_PeerIdentity *peer, +send_message (struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type) { @@ -1869,10 +1893,10 @@ send_message (const struct GNUNET_PeerIdentity *peer, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message to %s of type %s\n", - GNUNET_i2s (peer), + GNUNET_i2s (&peer_ctx->peer_id), type); - pending_msg = insert_pending_message (peer, ev, type); - mq = get_mq (peer); + pending_msg = insert_pending_message (peer_ctx, ev, type); + mq = get_mq (peer_ctx); GNUNET_MQ_notify_sent (ev, mq_notify_sent_cb, pending_msg); @@ -1884,28 +1908,29 @@ send_message (const struct GNUNET_PeerIdentity *peer, * * Avoids scheduling an operation twice. * - * @param peer the peer we want to schedule the operation for once it gets - * online + * @param peer_ctx Context of the peer for which to schedule the operation + * @param peer_op the operation to schedule + * @param cls Closure to @a peer_op * * @return #GNUNET_YES if the operation was scheduled * #GNUNET_NO otherwise */ static int -schedule_operation (const struct GNUNET_PeerIdentity *peer, - const PeerOp peer_op) +schedule_operation (struct PeerContext *peer_ctx, + const PeerOp peer_op, + void *cls) { struct PeerPendingOp pending_op; - struct PeerContext *peer_ctx; - GNUNET_assert (GNUNET_YES == check_peer_known (peer)); + GNUNET_assert (GNUNET_YES == check_peer_known (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)); //TODO if ONLINE execute immediately - if (GNUNET_NO == check_operation_scheduled (peer, peer_op)) + if (GNUNET_NO == check_operation_scheduled (peer_ctx, peer_op)) { - peer_ctx = get_peer_ctx (peer); pending_op.op = peer_op; - pending_op.op_cls = NULL; + pending_op.op_cls = cls; GNUNET_array_append (peer_ctx->pending_ops, peer_ctx->num_pending_ops, pending_op); @@ -1983,6 +2008,11 @@ struct ClientContext * The client handle to send the reply to */ struct GNUNET_SERVICE_Client *client; + + /** + * The #SubSampler this context belongs to + */ + struct SubSampler *ss; }; /** @@ -2079,27 +2109,36 @@ insert_in_view_op (void *cls, * * Called once we know a peer is online. * + * @param ss SubSampler in with the view to insert in + * @param peer the peer to insert + * * @return GNUNET_OK if peer was actually inserted * GNUNET_NO if peer was not inserted */ static int -insert_in_view (const struct GNUNET_PeerIdentity *peer) +insert_in_view (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { + struct PeerContext *peer_ctx; int online; int ret; - online = check_peer_flag (peer, Peers_ONLINE); + online = check_peer_flag (ss->peer_map, peer, Peers_ONLINE); + peer_ctx = get_peer_ctx (ss->peer_map, peer); // TODO indirection needed? if ( (GNUNET_NO == online) || (GNUNET_SYSERR == online) ) /* peer is not even known */ { - (void) issue_peer_online_check (peer); - (void) schedule_operation (peer, insert_in_view_op); + (void) issue_peer_online_check (ss, peer); + (void) schedule_operation (peer_ctx, insert_in_view_op, NULL); return GNUNET_NO; } /* Open channel towards peer to keep connection open */ - indicate_sending_intention (peer); - ret = View_put (mss->view, peer); - GNUNET_STATISTICS_set (stats, "view size", View_size(mss->view), GNUNET_NO); + indicate_sending_intention (peer_ctx); + ret = View_put (ss->view, peer); + GNUNET_STATISTICS_set (stats, + "view size", + View_size (peer_ctx->ss->view), + GNUNET_NO); return ret; } @@ -2111,7 +2150,7 @@ insert_in_view (const struct GNUNET_PeerIdentity *peer) * @param view_array the peerids of the view as array (can be empty) * @param view_size the size of the view array (can be 0) */ -void +static void send_view (const struct ClientContext *cli_ctx, const struct GNUNET_PeerIdentity *view_array, uint64_t view_size) @@ -2121,8 +2160,8 @@ send_view (const struct ClientContext *cli_ctx, if (NULL == view_array) { - view_size = View_size (mss->view); - view_array = View_get_as_array(mss->view); + view_size = View_size (cli_ctx->ss->view); + view_array = View_get_as_array (cli_ctx->ss->view); } ev = GNUNET_MQ_msg_extra (out_msg, @@ -2146,7 +2185,7 @@ send_view (const struct ClientContext *cli_ctx, * @param view_array the peerids of the view as array (can be empty) * @param view_size the size of the view array (can be 0) */ -void +static void send_stream_peers (const struct ClientContext *cli_ctx, uint64_t num_peers, const struct GNUNET_PeerIdentity *peers) @@ -2170,16 +2209,18 @@ send_stream_peers (const struct ClientContext *cli_ctx, /** * @brief sends updates to clients that are interested + * + * @param ss Subsampler for which to notify clients */ static void -clients_notify_view_update (void) +clients_notify_view_update (const struct SubSampler *ss) { struct ClientContext *cli_ctx_iter; uint64_t num_peers; const struct GNUNET_PeerIdentity *view_array; - num_peers = View_size (mss->view); - view_array = View_get_as_array(mss->view); + num_peers = View_size (ss->view); + view_array = View_get_as_array(ss->view); /* check size of view is small enough */ if (GNUNET_MAX_MESSAGE_SIZE < num_peers) { @@ -2214,6 +2255,9 @@ clients_notify_view_update (void) /** * @brief sends updates to clients that are interested + * + * @param num_peers Number of peers to send + * @param peers the array of peers to send */ static void clients_notify_stream_peer (uint64_t num_peers, @@ -2237,8 +2281,13 @@ clients_notify_stream_peer (uint64_t num_peers, } } + /** * Put random peer from sampler into the view as history update. + * + * @param ids Array of Peers to insert into view + * @param num_peers Number of peers to insert + * @param cls Closure - The SubSampler for which this is to be done */ static void hist_update (const struct GNUNET_PeerIdentity *ids, @@ -2246,21 +2295,21 @@ hist_update (const struct GNUNET_PeerIdentity *ids, void *cls) { unsigned int i; - (void) cls; + struct SubSampler *ss = cls; for (i = 0; i < num_peers; i++) { int inserted; - inserted = insert_in_view (&ids[i]); + inserted = insert_in_view (ss, &ids[i]); if (GNUNET_OK == inserted) { clients_notify_stream_peer (1, &ids[i]); } - to_file (mss->file_name_view_log, + to_file (ss->file_name_view_log, "+%s\t(hist)", GNUNET_i2s_full (ids)); } - clients_notify_view_update(); + clients_notify_view_update (ss); } @@ -2269,6 +2318,9 @@ hist_update (const struct GNUNET_PeerIdentity *ids, * * If we do not have enough sampler elements, double current sampler size * If we have more than enough sampler elements, halv current sampler size + * + * @param sampler The sampler to resize + * @param new_size New size to which to resize */ static void resize_wrapper (struct RPS_Sampler *sampler, uint32_t new_size) @@ -2327,12 +2379,12 @@ add_peer_array_to_set (const struct GNUNET_PeerIdentity *peer_array, /** * Send a PULL REPLY to @a peer_id * - * @param peer_id the peer to send the reply to. + * @param peer_ctx Context of the peer to send the reply to * @param peer_ids the peers to send to @a peer_id * @param num_peer_ids the number of peers to send to @a peer_id */ static void -send_pull_reply (const struct GNUNET_PeerIdentity *peer_id, +send_pull_reply (struct PeerContext *peer_ctx, const struct GNUNET_PeerIdentity *peer_ids, unsigned int num_peer_ids) { @@ -2358,7 +2410,7 @@ send_pull_reply (const struct GNUNET_PeerIdentity *peer_id, LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to send PULL REPLY with %u peers to %s\n", - send_size, GNUNET_i2s (peer_id)); + send_size, GNUNET_i2s (&peer_ctx->peer_id)); ev = GNUNET_MQ_msg_extra (out_msg, send_size * sizeof (struct GNUNET_PeerIdentity), @@ -2367,7 +2419,7 @@ send_pull_reply (const struct GNUNET_PeerIdentity *peer_id, GNUNET_memcpy (&out_msg[1], peer_ids, send_size * sizeof (struct GNUNET_PeerIdentity)); - send_message (peer_id, ev, "PULL REPLY"); + send_message (peer_ctx, ev, "PULL REPLY"); GNUNET_STATISTICS_update(stats, "# pull reply send issued", 1, GNUNET_NO); // TODO check with send intention: as send_channel is used/opened we indicate // a sending intention without intending it. @@ -2380,13 +2432,17 @@ send_pull_reply (const struct GNUNET_PeerIdentity *peer_id, * Insert PeerID in #pull_map * * Called once we know a peer is online. + * + * @param cls Closure - SubSampler with the pull map to insert into + * @param peer Peer to insert */ static void insert_in_pull_map (void *cls, const struct GNUNET_PeerIdentity *peer) { - (void) cls; - CustomPeerMap_put (mss->pull_map, peer); + struct SubSampler *ss = cls; + + CustomPeerMap_put (ss->pull_map, peer); } @@ -2395,15 +2451,18 @@ insert_in_pull_map (void *cls, * * Called once we know a peer is online. * Implements #PeerOp + * + * @param cls Closure - SubSampler with view to insert peer into + * @param peer the peer to insert */ static void insert_in_view_op (void *cls, const struct GNUNET_PeerIdentity *peer) { - (void) cls; + struct SubSampler *ss = cls; int inserted; - inserted = insert_in_view (peer); + inserted = insert_in_view (ss, peer); if (GNUNET_OK == inserted) { clients_notify_stream_peer (1, peer); @@ -2414,41 +2473,46 @@ insert_in_view_op (void *cls, /** * Update sampler with given PeerID. * Implements #PeerOp + * + * @param cls Closure - SubSampler containing the sampler to insert into + * @param peer Peer to insert */ static void insert_in_sampler (void *cls, const struct GNUNET_PeerIdentity *peer) { - (void) cls; + struct SubSampler *ss = cls; + LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating samplers with peer %s from insert_in_sampler()\n", GNUNET_i2s (peer)); - RPS_sampler_update (mss->sampler, peer); - if (0 < RPS_sampler_count_id (mss->sampler, peer)) + RPS_sampler_update (ss->sampler, peer); + if (0 < RPS_sampler_count_id (ss->sampler, peer)) { /* Make sure we 'know' about this peer */ - (void) issue_peer_online_check (peer); + (void) issue_peer_online_check (ss, peer); /* Establish a channel towards that peer to indicate we are going to send * messages to it */ //indicate_sending_intention (peer); } #ifdef TO_FILE - mss->num_observed_peers++; + ss->num_observed_peers++; GNUNET_CONTAINER_multipeermap_put - (mss->observed_unique_peers, + (ss->observed_unique_peers, peer, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); uint32_t num_observed_unique_peers = - GNUNET_CONTAINER_multipeermap_size (mss->observed_unique_peers); - to_file (mss->file_name_observed_log, + GNUNET_CONTAINER_multipeermap_size (ss->observed_unique_peers); + to_file (ss->file_name_observed_log, "%" PRIu32 " %" PRIu32 " %f\n", - mss->num_observed_peers, + ss->num_observed_peers, num_observed_unique_peers, - 1.0*num_observed_unique_peers/mss->num_observed_peers) + 1.0*num_observed_unique_peers/ss->num_observed_peers) #endif /* TO_FILE */ } + /** * @brief This is called on peers from external sources (cadet, peerinfo, ...) * If the peer is not known, online check is issued and it is @@ -2456,16 +2520,20 @@ insert_in_sampler (void *cls, * * "External sources" refer to every source except the gossip. * - * @param peer peer to insert + * @param ss SubSampler for which @a peer was received + * @param peer peer to insert/peer received */ static void -got_peer (const struct GNUNET_PeerIdentity *peer) +got_peer (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { /* If we did not know this peer already, insert it into sampler and view */ - if (GNUNET_YES == issue_peer_online_check (peer)) + if (GNUNET_YES == issue_peer_online_check (ss, peer)) { - schedule_operation (peer, insert_in_sampler); - schedule_operation (peer, insert_in_view_op); + schedule_operation (get_peer_ctx (ss->peer_map, peer), + &insert_in_sampler, ss); + schedule_operation (get_peer_ctx (ss->peer_map, peer), + &insert_in_view_op, ss); } GNUNET_STATISTICS_update (stats, "# learnd peers", @@ -2473,28 +2541,36 @@ got_peer (const struct GNUNET_PeerIdentity *peer) GNUNET_NO); } + /** * @brief Checks if there is a sending channel and if it is needed * - * @param peer the peer whose sending channel is checked + * @param peer_ctx Context of the peer to check * @return GNUNET_YES if sending channel exists and is still needed * GNUNET_NO otherwise */ static int -check_sending_channel_needed (const struct GNUNET_PeerIdentity *peer) +check_sending_channel_needed (const struct PeerContext *peer_ctx) { /* struct GNUNET_CADET_Channel *channel; */ - if (GNUNET_NO == check_peer_known (peer)) + if (GNUNET_NO == check_peer_known (peer_ctx->ss->peer_map, + &peer_ctx->peer_id)) { return GNUNET_NO; } - if (GNUNET_YES == check_sending_channel_exists (peer)) + if (GNUNET_YES == check_sending_channel_exists (peer_ctx)) { - if ( (0 < RPS_sampler_count_id (mss->sampler, peer)) || - (GNUNET_YES == View_contains_peer (mss->view, peer)) || - (GNUNET_YES == CustomPeerMap_contains_peer (mss->push_map, peer)) || - (GNUNET_YES == CustomPeerMap_contains_peer (mss->pull_map, peer)) || - (GNUNET_YES == check_peer_flag (peer, Peers_PULL_REPLY_PENDING))) + if ( (0 < RPS_sampler_count_id (peer_ctx->ss->sampler, + &peer_ctx->peer_id)) || + (GNUNET_YES == View_contains_peer (peer_ctx->ss->view, + &peer_ctx->peer_id)) || + (GNUNET_YES == CustomPeerMap_contains_peer (peer_ctx->ss->push_map, + &peer_ctx->peer_id)) || + (GNUNET_YES == CustomPeerMap_contains_peer (peer_ctx->ss->pull_map, + &peer_ctx->peer_id)) || + (GNUNET_YES == check_peer_flag (peer_ctx->ss->peer_map, + &peer_ctx->peer_id, + Peers_PULL_REPLY_PENDING))) { /* If we want to keep the connection to peer open */ return GNUNET_YES; } @@ -2503,20 +2579,23 @@ check_sending_channel_needed (const struct GNUNET_PeerIdentity *peer) return GNUNET_NO; } + /** * @brief remove peer from our knowledge, the view, push and pull maps and * samplers. * + * @param ss SubSampler with the data structures the peer is to be removed from * @param peer the peer to remove */ static void -remove_peer (const struct GNUNET_PeerIdentity *peer) +remove_peer (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { - (void) View_remove_peer (mss->view, peer); - CustomPeerMap_remove_peer (mss->pull_map, peer); - CustomPeerMap_remove_peer (mss->push_map, peer); - RPS_sampler_reinitialise_by_value (mss->sampler, peer); - destroy_peer (get_peer_ctx (peer)); + (void) View_remove_peer (ss->view, peer); + CustomPeerMap_remove_peer (ss->pull_map, peer); + CustomPeerMap_remove_peer (ss->push_map, peer); + RPS_sampler_reinitialise_by_value (ss->sampler, peer); + destroy_peer (get_peer_ctx (ss->peer_map, peer)); } @@ -2525,35 +2604,39 @@ remove_peer (const struct GNUNET_PeerIdentity *peer) * * If the sending channel is no longer needed it is destroyed. * + * @param ss SubSamper in which the current peer is to be cleaned * @param peer the peer whose data is about to be cleaned */ static void -clean_peer (const struct GNUNET_PeerIdentity *peer) +clean_peer (struct SubSampler *ss, + const struct GNUNET_PeerIdentity *peer) { - if (GNUNET_NO == check_sending_channel_needed (peer)) + if (GNUNET_NO == check_sending_channel_needed (get_peer_ctx (ss->peer_map, + peer))) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to remove send channel to peer %s\n", GNUNET_i2s (peer)); #ifdef ENABLE_MALICIOUS if (0 != GNUNET_CRYPTO_cmp_peer_identity (&attacked_peer, peer)) - (void) destroy_sending_channel (peer); + (void) destroy_sending_channel (get_peer_ctx (ss->peer_map, peer)); #else /* ENABLE_MALICIOUS */ - (void) destroy_sending_channel (peer); + (void) destroy_sending_channel (get_peer_ctx (ss->peer_map, peer)); #endif /* ENABLE_MALICIOUS */ } - if ( (GNUNET_NO == check_peer_send_intention (peer)) && - (GNUNET_NO == View_contains_peer (mss->view, peer)) && - (GNUNET_NO == CustomPeerMap_contains_peer (mss->push_map, peer)) && - (GNUNET_NO == CustomPeerMap_contains_peer (mss->push_map, peer)) && - (0 == RPS_sampler_count_id (mss->sampler, peer)) && - (GNUNET_NO != check_removable (peer)) ) + if ( (GNUNET_NO == check_peer_send_intention (get_peer_ctx (ss->peer_map, + peer))) && + (GNUNET_NO == View_contains_peer (ss->view, peer)) && + (GNUNET_NO == CustomPeerMap_contains_peer (ss->push_map, peer)) && + (GNUNET_NO == CustomPeerMap_contains_peer (ss->push_map, peer)) && + (0 == RPS_sampler_count_id (ss->sampler, peer)) && + (GNUNET_NO != check_removable (get_peer_ctx (ss->peer_map, peer))) ) { /* We can safely remove this peer */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to remove peer %s\n", GNUNET_i2s (peer)); - remove_peer (peer); + remove_peer (ss, peer); return; } } @@ -2567,9 +2650,8 @@ clean_peer (const struct GNUNET_PeerIdentity *peer) * Also check if the knowledge about this peer is still needed. * If not, remove this peer from our knowledge. * - * @param cls The closure + * @param cls The closure - Context to the channel * @param channel The channel being closed - * @param channel_ctx The context associated with this channel */ static void cleanup_destroyed_channel (void *cls, @@ -2577,7 +2659,6 @@ cleanup_destroyed_channel (void *cls, { struct ChannelCtx *channel_ctx = cls; struct PeerContext *peer_ctx = channel_ctx->peer_ctx; - (void) cls; (void) channel; channel_ctx->channel = NULL; @@ -2585,7 +2666,7 @@ cleanup_destroyed_channel (void *cls, if (NULL != peer_ctx && peer_ctx->send_channel_ctx == channel_ctx) { - remove_peer (&peer_ctx->peer_id); + remove_peer (peer_ctx->ss, &peer_ctx->peer_id); } } @@ -2599,6 +2680,16 @@ cleanup_destroyed_channel (void *cls, * SubSampler ***********************************************************************/ +/** + * @brief Create a new SUbSampler + * + * @param shared_value Value shared among rps instances on other hosts that + * defines a subgroup to sample from. + * @param sampler_size Size of the sampler + * @param round_interval Interval (in average) between two rounds + * + * @return SubSampler + */ struct SubSampler * new_subsampler (const char *shared_value, uint32_t sampler_size, @@ -2640,7 +2731,7 @@ new_subsampler (const char *shared_value, GNUNET_CADET_open_port (ss->cadet_handle, &ss->port, &handle_inbound_channel, /* Connect handler */ - NULL, /* cls */ + ss, /* cls */ NULL, /* WindowSize handler */ &cleanup_destroyed_channel, /* Disconnect handler */ cadet_handlers); @@ -2703,6 +2794,11 @@ new_subsampler (const char *shared_value, ***********************************************************************/ +/** + * @brief Destroy the context for a (connected) client + * + * @param cli_ctx Context to destroy + */ static void destroy_cli_ctx (struct ClientContext *cli_ctx) { @@ -2719,6 +2815,13 @@ destroy_cli_ctx (struct ClientContext *cli_ctx) * * Updates sizes of sampler list and view and adapt those lists * accordingly. + * + * implements #GNUNET_NSE_Callback + * + * @param cls Closure - SubSampler + * @param timestamp time when the estimate was received from the server (or created by the server) + * @param logestimate the log(Base 2) value of the current network size estimate + * @param std_dev standard deviation for the estimate */ static void nse_callback (void *cls, @@ -2727,34 +2830,34 @@ nse_callback (void *cls, { double estimate; //double scale; // TODO this might go gloabal/config - (void) cls; + struct SubSampler *ss = cls; (void) timestamp; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a ns estimate - logest: %f, std_dev: %f (old_size: %u)\n", - logestimate, std_dev, RPS_sampler_get_size (mss->sampler)); + logestimate, std_dev, RPS_sampler_get_size (ss->sampler)); //scale = .01; estimate = GNUNET_NSE_log_estimate_to_n (logestimate); // GNUNET_NSE_log_estimate_to_n (logestimate); estimate = pow (estimate, 1.0 / 3); // TODO add if std_dev is a number // estimate += (std_dev * scale); - if (mss->view_size_est_min < ceil (estimate)) + if (ss->view_size_est_min < ceil (estimate)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Changing estimate to %f\n", estimate); - mss->sampler_size_est_need = estimate; - mss->view_size_est_need = estimate; + ss->sampler_size_est_need = estimate; + ss->view_size_est_need = estimate; } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Not using estimate %f\n", estimate); - //mss->sampler_size_est_need = mss->view_size_est_min; - mss->view_size_est_need = mss->view_size_est_min; + //ss->sampler_size_est_need = ss->view_size_est_min; + ss->view_size_est_need = ss->view_size_est_min; } - GNUNET_STATISTICS_set (stats, "view size aim", mss->view_size_est_need, GNUNET_NO); + GNUNET_STATISTICS_set (stats, "view size aim", ss->view_size_est_need, GNUNET_NO); /* If the NSE has changed adapt the lists accordingly */ - resize_wrapper (mss->sampler, mss->sampler_size_est_need); - View_change_len (mss->view, mss->view_size_est_need); + resize_wrapper (ss->sampler, ss->sampler_size_est_need); + View_change_len (ss->view, ss->view_size_est_need); } @@ -2765,6 +2868,7 @@ nse_callback (void *cls, * @param cls the closure (#ClientContext) * @param msg the message * @return #GNUNET_OK if @a msg is well-formed + * #GNUNET_SYSERR otherwise */ static int check_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg) @@ -2814,7 +2918,7 @@ handle_client_seed (void *cls, i, GNUNET_i2s (&peers[i])); - got_peer (&peers[i]); + got_peer (cli_ctx->ss, &peers[i]); } GNUNET_SERVICE_client_continue (cli_ctx->client); } @@ -2824,7 +2928,8 @@ handle_client_seed (void *cls, * Handle RPS request from the client. * * @param cls Client context - * @param message unused + * @param message Message containing the numer of updates the client wants to + * receive */ static void handle_client_view_request (void *cls, @@ -2926,8 +3031,8 @@ handle_client_stream_cancel (void *cls, * This does nothing. But without calling #GNUNET_CADET_receive_done() * the channel is blocked for all other communication. * - * @param cls Closure - * @param msg The message header + * @param cls Closure - Context of channel + * @param msg Message - unused */ static void handle_peer_check (void *cls, @@ -2947,14 +3052,15 @@ handle_peer_check (void *cls, GNUNET_CADET_receive_done (channel_ctx->channel); } + /** * Handle a PUSH message from another peer. * * Check the proof of work and store the PeerID * in the temporary list for pushed PeerIDs. * - * @param cls Closure - * @param msg The message header + * @param cls Closure - Context of channel + * @param msg Message - unused */ static void handle_peer_push (void *cls, @@ -2981,9 +3087,8 @@ handle_peer_push (void *cls, tmp_att_peer->peer_id = *peer; if (NULL == att_peer_set) att_peer_set = GNUNET_CONTAINER_multipeermap_create (1, GNUNET_NO); - if (GNUNET_NO == - GNUNET_CONTAINER_multipeermap_contains (att_peer_set, - peer)) + if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set, + peer)) { GNUNET_CONTAINER_DLL_insert (att_peers_head, att_peers_tail, @@ -3004,9 +3109,10 @@ handle_peer_push (void *cls, #endif /* ENABLE_MALICIOUS */ /* Add the sending peer to the push_map */ - CustomPeerMap_put (mss->push_map, peer); + CustomPeerMap_put (channel_ctx->peer_ctx->ss->push_map, peer); - GNUNET_break_op (check_peer_known (peer)); + GNUNET_break_op (check_peer_known (channel_ctx->peer_ctx->ss->peer_map, + &channel_ctx->peer_ctx->peer_id)); GNUNET_CADET_receive_done (channel_ctx->channel); } @@ -3016,15 +3122,16 @@ handle_peer_push (void *cls, * * Reply with the view of PeerIDs. * - * @param cls Closure - * @param msg The message header + * @param cls Closure - Context of channel + * @param msg Message - unused */ static void handle_peer_pull_request (void *cls, const struct GNUNET_MessageHeader *msg) { const struct ChannelCtx *channel_ctx = cls; - const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id; + struct PeerContext *peer_ctx = channel_ctx->peer_ctx; + const struct GNUNET_PeerIdentity *peer = &peer_ctx->peer_id; const struct GNUNET_PeerIdentity *view_array; (void) msg; @@ -3035,22 +3142,25 @@ handle_peer_pull_request (void *cls, if (1 == mal_type || 3 == mal_type) { /* Try to maximise representation */ - send_pull_reply (peer, mal_peers, num_mal_peers); + send_pull_reply (peer_ctx, mal_peers, num_mal_peers); } else if (2 == mal_type) { /* Try to partition network */ if (0 == GNUNET_CRYPTO_cmp_peer_identity (&attacked_peer, peer)) { - send_pull_reply (peer, mal_peers, num_mal_peers); + send_pull_reply (peer_ctx, mal_peers, num_mal_peers); } } #endif /* ENABLE_MALICIOUS */ - GNUNET_break_op (check_peer_known (peer)); + GNUNET_break_op (check_peer_known (channel_ctx->peer_ctx->ss->peer_map, + &channel_ctx->peer_ctx->peer_id)); GNUNET_CADET_receive_done (channel_ctx->channel); - view_array = View_get_as_array (mss->view); - send_pull_reply (peer, view_array, View_size (mss->view)); + view_array = View_get_as_array (channel_ctx->peer_ctx->ss->view); + send_pull_reply (peer_ctx, + view_array, + View_size (channel_ctx->peer_ctx->ss->view)); } @@ -3058,8 +3168,8 @@ handle_peer_pull_request (void *cls, * Check whether we sent a corresponding request and * whether this reply is the first one. * - * @param cls Closure - * @param msg The message header + * @param cls Closure - Context of channel + * @param msg Message containing the replied peers */ static int check_peer_pull_reply (void *cls, @@ -3086,7 +3196,8 @@ check_peer_pull_reply (void *cls, return GNUNET_SYSERR; } - if (GNUNET_YES != check_peer_flag (&sender_ctx->peer_id, + if (GNUNET_YES != check_peer_flag (sender_ctx->ss->peer_map, + &sender_ctx->peer_id, Peers_PULL_REPLY_PENDING)) { LOG (GNUNET_ERROR_TYPE_WARNING, @@ -3102,6 +3213,7 @@ check_peer_pull_reply (void *cls, return GNUNET_OK; } + /** * Handle PULL REPLY message from another peer. * @@ -3165,23 +3277,28 @@ handle_peer_pull_reply (void *cls, } #endif /* ENABLE_MALICIOUS */ /* Make sure we 'know' about this peer */ - (void) insert_peer (&peers[i]); + (void) insert_peer (channel_ctx->peer_ctx->ss, &peers[i]); - if (GNUNET_YES == check_peer_valid (&peers[i])) + if (GNUNET_YES == check_peer_valid (channel_ctx->peer_ctx->ss->valid_peers, + &peers[i])) { - CustomPeerMap_put (mss->pull_map, &peers[i]); + CustomPeerMap_put (channel_ctx->peer_ctx->ss->pull_map, &peers[i]); } else { - schedule_operation (&peers[i], insert_in_pull_map); - (void) issue_peer_online_check (&peers[i]); + schedule_operation (channel_ctx->peer_ctx, + insert_in_pull_map, + channel_ctx->peer_ctx->ss); /* cls */ + (void) issue_peer_online_check (channel_ctx->peer_ctx->ss, &peers[i]); } } - UNSET_PEER_FLAG (get_peer_ctx (sender), Peers_PULL_REPLY_PENDING); - clean_peer (sender); + UNSET_PEER_FLAG (get_peer_ctx (channel_ctx->peer_ctx->ss->peer_map, sender), + Peers_PULL_REPLY_PENDING); + clean_peer (channel_ctx->peer_ctx->ss, sender); - GNUNET_break_op (check_peer_known (sender)); + GNUNET_break_op (check_peer_known (channel_ctx->peer_ctx->ss->peer_map, + sender)); GNUNET_CADET_receive_done (channel_ctx->channel); } @@ -3193,12 +3310,12 @@ handle_peer_pull_reply (void *cls, * For example for mean 4 min and spread 2 the minimum is (4 min - (1/2 * 4 min)) * It would return a random value between 2 and 6 min. * - * @param mean the mean + * @param mean the mean time until the next round * @param spread the inverse amount of deviation from the mean */ static struct GNUNET_TIME_Relative compute_rand_delay (struct GNUNET_TIME_Relative mean, - unsigned int spread) + unsigned int spread) { struct GNUNET_TIME_Relative half_interval; struct GNUNET_TIME_Relative ret; @@ -3238,23 +3355,24 @@ compute_rand_delay (struct GNUNET_TIME_Relative mean, /** * Send single pull request * - * @param peer_id the peer to send the pull request to. + * @param peer_ctx Context to the peer to send request to */ static void -send_pull_request (const struct GNUNET_PeerIdentity *peer) +send_pull_request (struct PeerContext *peer_ctx) { struct GNUNET_MQ_Envelope *ev; - GNUNET_assert (GNUNET_NO == check_peer_flag (peer, - Peers_PULL_REPLY_PENDING)); - SET_PEER_FLAG (get_peer_ctx (peer), Peers_PULL_REPLY_PENDING); + GNUNET_assert (GNUNET_NO == check_peer_flag (peer_ctx->ss->peer_map, + &peer_ctx->peer_id, + Peers_PULL_REPLY_PENDING)); + SET_PEER_FLAG (peer_ctx, Peers_PULL_REPLY_PENDING); LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to send PULL REQUEST to peer %s.\n", - GNUNET_i2s (peer)); + GNUNET_i2s (&peer_ctx->peer_id)); ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST); - send_message (peer, ev, "PULL REQUEST"); + send_message (peer_ctx, ev, "PULL REQUEST"); GNUNET_STATISTICS_update(stats, "# pull request send issued", 1, GNUNET_NO); } @@ -3262,19 +3380,19 @@ send_pull_request (const struct GNUNET_PeerIdentity *peer) /** * Send single push * - * @param peer_id the peer to send the push to. + * @param peer_ctx Context of peer to send push to */ static void -send_push (const struct GNUNET_PeerIdentity *peer_id) +send_push (struct PeerContext *peer_ctx) { struct GNUNET_MQ_Envelope *ev; LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to send PUSH to peer %s.\n", - GNUNET_i2s (peer_id)); + GNUNET_i2s (&peer_ctx->peer_id)); ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PUSH); - send_message (peer_id, ev, "PUSH"); + send_message (peer_ctx, ev, "PUSH"); GNUNET_STATISTICS_update(stats, "# push send issued", 1, GNUNET_NO); } @@ -3334,6 +3452,7 @@ handle_client_act_malicious (void *cls, struct GNUNET_PeerIdentity *peers; uint32_t num_mal_peers_sent; uint32_t num_mal_peers_old; + struct SubSampler *ss = cli_ctx->ss; /* Do actual logic */ peers = (struct GNUNET_PeerIdentity *) &msg[1]; @@ -3365,8 +3484,8 @@ handle_client_act_malicious (void *cls, mal_peer_set); /* Substitute do_round () with do_mal_round () */ - GNUNET_SCHEDULER_cancel (mss->do_round_task); - mss->do_round_task = GNUNET_SCHEDULER_add_now (&do_mal_round, NULL); + GNUNET_SCHEDULER_cancel (ss->do_round_task); + ss->do_round_task = GNUNET_SCHEDULER_add_now (&do_mal_round, ss); } else if ( (2 == mal_type) || @@ -3398,9 +3517,9 @@ handle_client_act_malicious (void *cls, &msg->attacked_peer, sizeof (struct GNUNET_PeerIdentity)); /* Set the flag of the attacked peer to valid to avoid problems */ - if (GNUNET_NO == check_peer_known (&attacked_peer)) + if (GNUNET_NO == check_peer_known (ss->peer_map, &attacked_peer)) { - (void) issue_peer_online_check (&attacked_peer); + (void) issue_peer_online_check (ss, &attacked_peer); } LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -3408,16 +3527,16 @@ handle_client_act_malicious (void *cls, GNUNET_i2s (&attacked_peer)); /* Substitute do_round () with do_mal_round () */ - GNUNET_SCHEDULER_cancel (mss->do_round_task); - mss->do_round_task = GNUNET_SCHEDULER_add_now (&do_mal_round, NULL); + GNUNET_SCHEDULER_cancel (ss->do_round_task); + ss->do_round_task = GNUNET_SCHEDULER_add_now (&do_mal_round, ss); } else if (0 == mal_type) { /* Stop acting malicious */ GNUNET_array_grow (mal_peers, num_mal_peers, 0); /* Substitute do_mal_round () with do_round () */ - GNUNET_SCHEDULER_cancel (mss->do_round_task); - mss->do_round_task = GNUNET_SCHEDULER_add_now (&do_round, NULL); + GNUNET_SCHEDULER_cancel (ss->do_round_task); + ss->do_round_task = GNUNET_SCHEDULER_add_now (&do_round, ss); } else { @@ -3432,6 +3551,8 @@ handle_client_act_malicious (void *cls, * Send out PUSHes and PULLs maliciously. * * This is executed regylary. + * + * @param cls Closure - SubSamper */ static void do_mal_round (void *cls) @@ -3440,12 +3561,12 @@ do_mal_round (void *cls) uint32_t i; struct GNUNET_TIME_Relative time_next_round; struct AttackedPeer *tmp_att_peer; - (void) cls; + struct SubSampler *ss = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to execute next round maliciously type %" PRIu32 ".\n", mal_type); - mss->do_round_task = NULL; + ss->do_round_task = NULL; GNUNET_assert (mal_type <= 3); /* Do malicious actions */ if (1 == mal_type) @@ -3468,7 +3589,7 @@ do_mal_round (void *cls) else att_peer_index = att_peer_index->next; - send_push (&att_peer_index->peer_id); + send_push (get_peer_ctx (ss->peer_map, &att_peer_index->peer_id)); } /* Send PULLs to some peers to learn about additional peers to attack */ @@ -3480,7 +3601,7 @@ do_mal_round (void *cls) else att_peer_index = tmp_att_peer->next; - send_pull_request (&tmp_att_peer->peer_id); + send_pull_request (get_peer_ctx (ss->peer_map, &tmp_att_peer->peer_id)); } } @@ -3491,9 +3612,11 @@ do_mal_round (void *cls) * Send as many pushes to the attacked peer as possible * That is one push per round as it will ignore more. */ - (void) issue_peer_online_check (&attacked_peer); - if (GNUNET_YES == check_peer_flag (&attacked_peer, Peers_ONLINE)) - send_push (&attacked_peer); + (void) issue_peer_online_check (ss, &attacked_peer); + if (GNUNET_YES == check_peer_flag (ss->peer_map, + &attacked_peer, + Peers_ONLINE)) + send_push (get_peer_ctx (ss->peer_map, &attacked_peer)); } @@ -3501,18 +3624,20 @@ do_mal_round (void *cls) { /* Combined attack */ /* Send PUSH to attacked peers */ - if (GNUNET_YES == check_peer_known (&attacked_peer)) + if (GNUNET_YES == check_peer_known (ss->peer_map, &attacked_peer)) { - (void) issue_peer_online_check (&attacked_peer); - if (GNUNET_YES == check_peer_flag (&attacked_peer, Peers_ONLINE)) + (void) issue_peer_online_check (ss, &attacked_peer); + if (GNUNET_YES == check_peer_flag (ss->peer_map, + &attacked_peer, + Peers_ONLINE)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Goding to send push to attacked peer (%s)\n", GNUNET_i2s (&attacked_peer)); - send_push (&attacked_peer); + send_push (get_peer_ctx (ss->peer_map, &attacked_peer)); } } - (void) issue_peer_online_check (&attacked_peer); + (void) issue_peer_online_check (ss, &attacked_peer); /* The maximum of pushes we're going to send this round */ num_pushes = GNUNET_MIN (GNUNET_MIN (push_limit - 1, @@ -3530,7 +3655,7 @@ do_mal_round (void *cls) else att_peer_index = att_peer_index->next; - send_push (&att_peer_index->peer_id); + send_push (get_peer_ctx (ss->peer_map, &att_peer_index->peer_id)); } /* Send PULLs to some peers to learn about additional peers to attack */ @@ -3542,18 +3667,18 @@ do_mal_round (void *cls) else att_peer_index = tmp_att_peer->next; - send_pull_request (&tmp_att_peer->peer_id); + send_pull_request (get_peer_ctx (ss->peer_map, &tmp_att_peer->peer_id)); } } /* Schedule next round */ - time_next_round = compute_rand_delay (mss->round_interval, 2); + time_next_round = compute_rand_delay (ss->round_interval, 2); - //mss->do_round_task = GNUNET_SCHEDULER_add_delayed (mss->round_interval, &do_mal_round, + //ss->do_round_task = GNUNET_SCHEDULER_add_delayed (ss->round_interval, &do_mal_round, //NULL); - GNUNET_assert (NULL == mss->do_round_task); - mss->do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round, - &do_mal_round, NULL); + GNUNET_assert (NULL == ss->do_round_task); + ss->do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round, + &do_mal_round, ss); LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished round\n"); } #endif /* ENABLE_MALICIOUS */ @@ -3562,6 +3687,8 @@ do_mal_round (void *cls) * Send out PUSHes and PULLs, possibly update #view, samplers. * * This is executed regylary. + * + * @param cls Closure - SubSampler */ static void do_round (void *cls) @@ -3575,64 +3702,66 @@ do_round (void *cls) uint32_t second_border; struct GNUNET_PeerIdentity peer; struct GNUNET_PeerIdentity *update_peer; - (void) cls; + struct SubSampler *ss = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to execute next round.\n"); GNUNET_STATISTICS_update(stats, "# rounds", 1, GNUNET_NO); - mss->do_round_task = NULL; + ss->do_round_task = NULL; LOG (GNUNET_ERROR_TYPE_DEBUG, "Printing view:\n"); - to_file (mss->file_name_view_log, + to_file (ss->file_name_view_log, "___ new round ___"); - view_array = View_get_as_array (mss->view); - for (i = 0; i < View_size (mss->view); i++) + view_array = View_get_as_array (ss->view); + for (i = 0; i < View_size (ss->view); i++) { LOG (GNUNET_ERROR_TYPE_DEBUG, "\t%s\n", GNUNET_i2s (&view_array[i])); - to_file (mss->file_name_view_log, + to_file (ss->file_name_view_log, "=%s\t(do round)", GNUNET_i2s_full (&view_array[i])); } /* Send pushes and pull requests */ - if (0 < View_size (mss->view)) + if (0 < View_size (ss->view)) { permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG, - View_size (mss->view)); + View_size (ss->view)); /* Send PUSHes */ - a_peers = ceil (alpha * View_size (mss->view)); + a_peers = ceil (alpha * View_size (ss->view)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to send pushes to %u (ceil (%f * %u)) peers.\n", - a_peers, alpha, View_size (mss->view)); + a_peers, alpha, View_size (ss->view)); for (i = 0; i < a_peers; i++) { peer = view_array[permut[i]]; // FIXME if this fails schedule/loop this for later - send_push (&peer); + send_push (get_peer_ctx (ss->peer_map, &peer)); } /* Send PULL requests */ - b_peers = ceil (beta * View_size (mss->view)); + b_peers = ceil (beta * View_size (ss->view)); first_border = a_peers; second_border = a_peers + b_peers; - if (second_border > View_size (mss->view)) + if (second_border > View_size (ss->view)) { - first_border = View_size (mss->view) - b_peers; - second_border = View_size (mss->view); + first_border = View_size (ss->view) - b_peers; + second_border = View_size (ss->view); } LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to send pulls to %u (ceil (%f * %u)) peers.\n", - b_peers, beta, View_size (mss->view)); + b_peers, beta, View_size (ss->view)); for (i = first_border; i < second_border; i++) { peer = view_array[permut[i]]; - if ( GNUNET_NO == check_peer_flag (&peer, Peers_PULL_REPLY_PENDING)) + if ( GNUNET_NO == check_peer_flag (ss->peer_map, + &peer, + Peers_PULL_REPLY_PENDING)) { // FIXME if this fails schedule/loop this for later - send_pull_request (&peer); + send_pull_request (get_peer_ctx (ss->peer_map, &peer)); } } @@ -3644,9 +3773,9 @@ do_round (void *cls) /* Update view */ /* TODO see how many peers are in push-/pull- list! */ - if ((CustomPeerMap_size (mss->push_map) <= alpha * mss->view_size_est_need) && - (0 < CustomPeerMap_size (mss->push_map)) && - (0 < CustomPeerMap_size (mss->pull_map))) + if ((CustomPeerMap_size (ss->push_map) <= alpha * ss->view_size_est_need) && + (0 < CustomPeerMap_size (ss->push_map)) && + (0 < CustomPeerMap_size (ss->pull_map))) //if (GNUNET_YES) // disable blocking temporarily { /* If conditions for update are fulfilled, update */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Update of the view.\n"); @@ -3659,23 +3788,23 @@ do_round (void *cls) peers_to_clean_size = 0; GNUNET_array_grow (peers_to_clean, peers_to_clean_size, - View_size (mss->view)); + View_size (ss->view)); GNUNET_memcpy (peers_to_clean, view_array, - View_size (mss->view) * sizeof (struct GNUNET_PeerIdentity)); + View_size (ss->view) * sizeof (struct GNUNET_PeerIdentity)); /* Seems like recreating is the easiest way of emptying the peermap */ - View_clear (mss->view); - to_file (mss->file_name_view_log, + View_clear (ss->view); + to_file (ss->file_name_view_log, "--- emptied ---"); - first_border = GNUNET_MIN (ceil (alpha * mss->view_size_est_need), - CustomPeerMap_size (mss->push_map)); + first_border = GNUNET_MIN (ceil (alpha * ss->view_size_est_need), + CustomPeerMap_size (ss->push_map)); second_border = first_border + - GNUNET_MIN (floor (beta * mss->view_size_est_need), - CustomPeerMap_size (mss->pull_map)); + GNUNET_MIN (floor (beta * ss->view_size_est_need), + CustomPeerMap_size (ss->pull_map)); final_size = second_border + - ceil ((1 - (alpha + beta)) * mss->view_size_est_need); + ceil ((1 - (alpha + beta)) * ss->view_size_est_need); LOG (GNUNET_ERROR_TYPE_DEBUG, "first border: %" PRIu32 ", second border: %" PRIu32 ", final size: %"PRIu32 "\n", first_border, @@ -3684,18 +3813,19 @@ do_round (void *cls) /* Update view with peers received through PUSHes */ permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG, - CustomPeerMap_size (mss->push_map)); + CustomPeerMap_size (ss->push_map)); for (i = 0; i < first_border; i++) { int inserted; - inserted = insert_in_view (CustomPeerMap_get_peer_by_index (mss->push_map, + inserted = insert_in_view (ss, + CustomPeerMap_get_peer_by_index (ss->push_map, permut[i])); if (GNUNET_OK == inserted) { clients_notify_stream_peer (1, - CustomPeerMap_get_peer_by_index (mss->push_map, permut[i])); + CustomPeerMap_get_peer_by_index (ss->push_map, permut[i])); } - to_file (mss->file_name_view_log, + to_file (ss->file_name_view_log, "+%s\t(push list)", GNUNET_i2s_full (&view_array[i])); // TODO change the peer_flags accordingly @@ -3705,19 +3835,20 @@ do_round (void *cls) /* Update view with peers received through PULLs */ permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG, - CustomPeerMap_size (mss->pull_map)); + CustomPeerMap_size (ss->pull_map)); for (i = first_border; i < second_border; i++) { int inserted; - inserted = insert_in_view (CustomPeerMap_get_peer_by_index (mss->pull_map, - permut[i - first_border])); + inserted = insert_in_view (ss, + CustomPeerMap_get_peer_by_index (ss->pull_map, + permut[i - first_border])); if (GNUNET_OK == inserted) { clients_notify_stream_peer (1, - CustomPeerMap_get_peer_by_index (mss->pull_map, + CustomPeerMap_get_peer_by_index (ss->pull_map, permut[i - first_border])); } - to_file (mss->file_name_view_log, + to_file (ss->file_name_view_log, "+%s\t(pull list)", GNUNET_i2s_full (&view_array[i])); // TODO change the peer_flags accordingly @@ -3726,106 +3857,106 @@ do_round (void *cls) permut = NULL; /* Update view with peers from history */ - RPS_sampler_get_n_rand_peers (mss->sampler, + RPS_sampler_get_n_rand_peers (ss->sampler, final_size - second_border, hist_update, - NULL); + ss); // TODO change the peer_flags accordingly - for (i = 0; i < View_size (mss->view); i++) + for (i = 0; i < View_size (ss->view); i++) rem_from_list (&peers_to_clean, &peers_to_clean_size, &view_array[i]); /* Clean peers that were removed from the view */ for (i = 0; i < peers_to_clean_size; i++) { - to_file (mss->file_name_view_log, + to_file (ss->file_name_view_log, "-%s", GNUNET_i2s_full (&peers_to_clean[i])); - clean_peer (&peers_to_clean[i]); + clean_peer (ss, &peers_to_clean[i]); } GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0); - clients_notify_view_update(); + clients_notify_view_update (ss); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n"); GNUNET_STATISTICS_update(stats, "# rounds blocked", 1, GNUNET_NO); - if (CustomPeerMap_size (mss->push_map) > alpha * View_size (mss->view) && - !(0 >= CustomPeerMap_size (mss->pull_map))) + if (CustomPeerMap_size (ss->push_map) > alpha * View_size (ss->view) && + !(0 >= CustomPeerMap_size (ss->pull_map))) GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes", 1, GNUNET_NO); - if (CustomPeerMap_size (mss->push_map) > alpha * View_size (mss->view) && - (0 >= CustomPeerMap_size (mss->pull_map))) + if (CustomPeerMap_size (ss->push_map) > alpha * View_size (ss->view) && + (0 >= CustomPeerMap_size (ss->pull_map))) GNUNET_STATISTICS_update(stats, "# rounds blocked - too many pushes, no pull replies", 1, GNUNET_NO); - if (0 >= CustomPeerMap_size (mss->push_map) && - !(0 >= CustomPeerMap_size (mss->pull_map))) + if (0 >= CustomPeerMap_size (ss->push_map) && + !(0 >= CustomPeerMap_size (ss->pull_map))) GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes", 1, GNUNET_NO); - if (0 >= CustomPeerMap_size (mss->push_map) && - (0 >= CustomPeerMap_size (mss->pull_map))) + if (0 >= CustomPeerMap_size (ss->push_map) && + (0 >= CustomPeerMap_size (ss->pull_map))) GNUNET_STATISTICS_update(stats, "# rounds blocked - no pushes, no pull replies", 1, GNUNET_NO); - if (0 >= CustomPeerMap_size (mss->pull_map) && - CustomPeerMap_size (mss->push_map) > alpha * View_size (mss->view) && - 0 >= CustomPeerMap_size (mss->push_map)) + if (0 >= CustomPeerMap_size (ss->pull_map) && + CustomPeerMap_size (ss->push_map) > alpha * View_size (ss->view) && + 0 >= CustomPeerMap_size (ss->push_map)) GNUNET_STATISTICS_update(stats, "# rounds blocked - no pull replies", 1, GNUNET_NO); } // TODO independent of that also get some peers from CADET_get_peers()? GNUNET_STATISTICS_set (stats, "# peers in push map at end of round", - CustomPeerMap_size (mss->push_map), + CustomPeerMap_size (ss->push_map), GNUNET_NO); GNUNET_STATISTICS_set (stats, "# peers in pull map at end of round", - CustomPeerMap_size (mss->pull_map), + CustomPeerMap_size (ss->pull_map), GNUNET_NO); GNUNET_STATISTICS_set (stats, "# peers in view at end of round", - View_size (mss->view), + View_size (ss->view), GNUNET_NO); LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (mss->view%u) = %.2f)\n", - CustomPeerMap_size (mss->push_map), - CustomPeerMap_size (mss->pull_map), + "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (ss->view%u) = %.2f)\n", + CustomPeerMap_size (ss->push_map), + CustomPeerMap_size (ss->pull_map), alpha, - View_size (mss->view), - alpha * View_size (mss->view)); + View_size (ss->view), + alpha * View_size (ss->view)); /* Update samplers */ - for (i = 0; i < CustomPeerMap_size (mss->push_map); i++) + for (i = 0; i < CustomPeerMap_size (ss->push_map); i++) { - update_peer = CustomPeerMap_get_peer_by_index (mss->push_map, i); + update_peer = CustomPeerMap_get_peer_by_index (ss->push_map, i); LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating with peer %s from push list\n", GNUNET_i2s (update_peer)); - insert_in_sampler (NULL, update_peer); - clean_peer (update_peer); /* This cleans only if it is not in the view */ + insert_in_sampler (ss, update_peer); + clean_peer (ss, update_peer); /* This cleans only if it is not in the view */ } - for (i = 0; i < CustomPeerMap_size (mss->pull_map); i++) + for (i = 0; i < CustomPeerMap_size (ss->pull_map); i++) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating with peer %s from pull list\n", - GNUNET_i2s (CustomPeerMap_get_peer_by_index (mss->pull_map, i))); - insert_in_sampler (NULL, CustomPeerMap_get_peer_by_index (mss->pull_map, i)); + GNUNET_i2s (CustomPeerMap_get_peer_by_index (ss->pull_map, i))); + insert_in_sampler (ss, CustomPeerMap_get_peer_by_index (ss->pull_map, i)); /* This cleans only if it is not in the view */ - clean_peer (CustomPeerMap_get_peer_by_index (mss->pull_map, i)); + clean_peer (ss, CustomPeerMap_get_peer_by_index (ss->pull_map, i)); } /* Empty push/pull lists */ - CustomPeerMap_clear (mss->push_map); - CustomPeerMap_clear (mss->pull_map); + CustomPeerMap_clear (ss->push_map); + CustomPeerMap_clear (ss->pull_map); GNUNET_STATISTICS_set (stats, "view size", - View_size(mss->view), + View_size(ss->view), GNUNET_NO); struct GNUNET_TIME_Relative time_next_round; - time_next_round = compute_rand_delay (mss->round_interval, 2); + time_next_round = compute_rand_delay (ss->round_interval, 2); /* Schedule next round */ - mss->do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round, - &do_round, NULL); + ss->do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round, + &do_round, ss); LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished round\n"); } @@ -3835,6 +3966,15 @@ do_round (void *cls) * * It is called on every peer(ID) that cadet somehow has contact with. * We use those to initialise the sampler. + * + * implements #GNUNET_CADET_PeersCB + * + * @param cls Closure - SubSampler + * @param peer Peer, or NULL on "EOF". + * @param tunnel Do we have a tunnel towards this peer? + * @param n_paths Number of known paths towards this peer. + * @param best_path How long is the best path? + * (0 = unknown, 1 = ourselves, 2 = neighbor) */ void init_peer_cb (void *cls, @@ -3844,7 +3984,7 @@ init_peer_cb (void *cls, unsigned int best_path) // "How long is the best path? // (0 = unknown, 1 = ourselves, 2 = neighbor)" { - (void) cls; + struct SubSampler *ss = cls; (void) tunnel; (void) n_paths; (void) best_path; @@ -3854,16 +3994,17 @@ init_peer_cb (void *cls, LOG (GNUNET_ERROR_TYPE_DEBUG, "Got peer_id %s from cadet\n", GNUNET_i2s (peer)); - got_peer (peer); + got_peer (ss, peer); } } + /** * @brief Iterator function over stored, valid peers. * * We initialise the sampler with those. * - * @param cls the closure + * @param cls Closure - SubSampler * @param peer the peer id * @return #GNUNET_YES if we should continue to * iterate, @@ -3873,14 +4014,14 @@ static int valid_peers_iterator (void *cls, const struct GNUNET_PeerIdentity *peer) { - (void) cls; + struct SubSampler *ss = cls; if (NULL != peer) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Got stored, valid peer %s\n", GNUNET_i2s (peer)); - got_peer (peer); + got_peer (ss, peer); } return GNUNET_YES; } @@ -3889,7 +4030,7 @@ valid_peers_iterator (void *cls, /** * Iterator over peers from peerinfo. * - * @param cls closure + * @param cls Closure - SubSampler * @param peer id of the peer, NULL for last call * @param hello hello message for the peer (can be NULL) * @param error message @@ -3900,7 +4041,7 @@ process_peerinfo_peers (void *cls, const struct GNUNET_HELLO_Message *hello, const char *err_msg) { - (void) cls; + struct SubSampler *ss = cls; (void) hello; (void) err_msg; @@ -3909,7 +4050,7 @@ process_peerinfo_peers (void *cls, LOG (GNUNET_ERROR_TYPE_DEBUG, "Got peer_id %s from peerinfo\n", GNUNET_i2s (peer)); - got_peer (peer); + got_peer (ss, peer); } } @@ -3917,13 +4058,14 @@ process_peerinfo_peers (void *cls, /** * Task run during shutdown. * - * @param cls unused + * @param cls Closure - SubSampler containing all datastructures to clean */ static void shutdown_task (void *cls) { struct ClientContext *client_ctx; (void) cls; + struct SubSampler *ss = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "RPS service is going down\n"); @@ -3938,39 +4080,39 @@ shutdown_task (void *cls) GNUNET_PEERINFO_notify_cancel (peerinfo_notify_handle); GNUNET_PEERINFO_disconnect (peerinfo_handle); peerinfo_handle = NULL; - if (NULL != mss->do_round_task) + if (NULL != ss->do_round_task) { - GNUNET_SCHEDULER_cancel (mss->do_round_task); - mss->do_round_task = NULL; + GNUNET_SCHEDULER_cancel (ss->do_round_task); + ss->do_round_task = NULL; } - peers_terminate (); + peers_terminate (ss); GNUNET_NSE_disconnect (nse); - RPS_sampler_destroy (mss->sampler); - GNUNET_CADET_close_port (mss->cadet_port); - GNUNET_CADET_disconnect (mss->cadet_handle); - mss->cadet_handle = NULL; - View_destroy (mss->view); - CustomPeerMap_destroy (mss->push_map); - CustomPeerMap_destroy (mss->pull_map); + RPS_sampler_destroy (ss->sampler); + GNUNET_CADET_close_port (ss->cadet_port); + GNUNET_CADET_disconnect (ss->cadet_handle); + ss->cadet_handle = NULL; + View_destroy (ss->view); + CustomPeerMap_destroy (ss->push_map); + CustomPeerMap_destroy (ss->pull_map); if (NULL != stats) { GNUNET_STATISTICS_destroy (stats, - GNUNET_NO); + GNUNET_NO); stats = NULL; } #ifdef ENABLE_MALICIOUS struct AttackedPeer *tmp_att_peer; /* it is ok to free this const during shutdown: */ - GNUNET_free ((char *) mss->file_name_view_log); + GNUNET_free ((char *) ss->file_name_view_log); #ifdef TO_FILE - GNUNET_free ((char *) mss->file_name_observed_log); - GNUNET_CONTAINER_multipeermap_destroy (mss->observed_unique_peers); + GNUNET_free ((char *) ss->file_name_observed_log); + GNUNET_CONTAINER_multipeermap_destroy (ss->observed_unique_peers); #endif /* TO_FILE */ GNUNET_array_grow (mal_peers, - num_mal_peers, - 0); + num_mal_peers, + 0); if (NULL != mal_peer_set) GNUNET_CONTAINER_multipeermap_destroy (mal_peer_set); if (NULL != att_peer_set) @@ -3979,8 +4121,8 @@ shutdown_task (void *cls) { tmp_att_peer = att_peers_head; GNUNET_CONTAINER_DLL_remove (att_peers_head, - att_peers_tail, - tmp_att_peer); + att_peers_tail, + tmp_att_peer); GNUNET_free (tmp_att_peer); } #endif /* ENABLE_MALICIOUS */ @@ -3990,7 +4132,7 @@ shutdown_task (void *cls) /** * Handle client connecting to the service. * - * @param cls NULL + * @param cls unused * @param client the new client * @param mq the message queue of @a client * @return @a client @@ -4012,6 +4154,7 @@ client_connect_cb (void *cls, cli_ctx->view_updates_left = -1; cli_ctx->stream_update = GNUNET_NO; cli_ctx->client = client; + cli_ctx->ss = mss; GNUNET_CONTAINER_DLL_insert (cli_ctx_head, cli_ctx_tail, cli_ctx); @@ -4068,12 +4211,12 @@ run (void *cls, (void) service; GNUNET_log_setup ("rps", - GNUNET_error_type_to_string (GNUNET_ERROR_TYPE_DEBUG), - NULL); + GNUNET_error_type_to_string (GNUNET_ERROR_TYPE_DEBUG), + NULL); cfg = c; /* Get own ID */ GNUNET_CRYPTO_get_peer_identity (cfg, - &own_identity); // TODO check return value + &own_identity); // TODO check return value GNUNET_log (GNUNET_ERROR_TYPE_INFO, "STARTING SERVICE (rps) for peer [%s]\n", GNUNET_i2s (&own_identity)); @@ -4085,9 +4228,9 @@ run (void *cls, /* Get time interval from the configuration */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, - "RPS", - "ROUNDINTERVAL", - &round_interval)) + "RPS", + "ROUNDINTERVAL", + &round_interval)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "RPS", "ROUNDINTERVAL"); @@ -4115,14 +4258,10 @@ run (void *cls, &fn_valid_peers)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "rps", "FILENAME_VALID_PEERS"); + "rps", + "FILENAME_VALID_PEERS"); } - - /* connect to NSE */ - nse = GNUNET_NSE_connect (cfg, nse_callback, NULL); - - alpha = 0.45; beta = 0.45; @@ -4135,27 +4274,29 @@ run (void *cls, peerinfo_handle = GNUNET_PEERINFO_connect (cfg); + /* connect to NSE */ + nse = GNUNET_NSE_connect (cfg, nse_callback, mss); + //LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting peers from CADET\n"); - //GNUNET_CADET_get_peers (mss.cadet_handle, &init_peer_cb, NULL); + //GNUNET_CADET_get_peers (mss.cadet_handle, &init_peer_cb, mss); // TODO send push/pull to each of those peers? // TODO read stored valid peers from last run LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting stored valid peers\n"); - restore_valid_peers (); - get_valid_peers (valid_peers_iterator, NULL); + restore_valid_peers (mss); + get_valid_peers (mss->valid_peers, valid_peers_iterator, mss); peerinfo_notify_handle = GNUNET_PEERINFO_notify (cfg, GNUNET_NO, process_peerinfo_peers, - NULL); + mss); LOG (GNUNET_ERROR_TYPE_INFO, "Ready to receive requests from clients\n"); - mss->do_round_task = GNUNET_SCHEDULER_add_now (&do_round, NULL); + mss->do_round_task = GNUNET_SCHEDULER_add_now (&do_round, mss); LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled first round\n"); - GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, mss); stats = GNUNET_STATISTICS_create ("rps", cfg); - } diff --git a/src/rps/rps-test_util.h b/src/rps/rps-test_util.h index def52a0ac..02b4bb400 100644 --- a/src/rps/rps-test_util.h +++ b/src/rps/rps-test_util.h @@ -66,9 +66,9 @@ create_file (const char *name); # define to_file_w_len(file_name, len, ...) #endif /* TO_FILE */ -const char * +char * store_prefix_file_name (const struct GNUNET_PeerIdentity *peer, - const char *prefix); + const char *prefix); void to_file_raw (const char *file_name, const char *buf, size_t size_buf); -- cgit v1.2.3