GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-service-rps.c File Reference

rps service implementation More...

#include "platform.h"
#include "gnunet_applications.h"
#include "gnunet_util_lib.h"
#include "gnunet_cadet_service.h"
#include "gnunet_core_service.h"
#include "gnunet_peerstore_service.h"
#include "gnunet_nse_service.h"
#include "gnunet_statistics_service.h"
#include "rps.h"
#include "rps-test_util.h"
#include "gnunet-service-rps_sampler.h"
#include "gnunet-service-rps_custommap.h"
#include "gnunet-service-rps_view.h"
#include "gnunet_constants.h"
#include <math.h>
#include <inttypes.h>
#include <string.h>
Include dependency graph for gnunet-service-rps.c:

Go to the source code of this file.

Data Structures

struct  PeerPendingOp
 Pending operation on peer consisting of callback and closure. More...
 
struct  PendingMessage
 List containing all messages that are yet to be send. More...
 
struct  PeerContext
 Struct used to keep track of other peer's status. More...
 
struct  PeersIteratorCls
 Closure to valid_peer_iterator. More...
 
struct  ChannelCtx
 Context for a channel. More...
 
struct  Sub
 One Sub. More...
 
struct  GetRandPeerIteratorCls
 The closure to get_rand_peer_iterator. More...
 
struct  ReplyCls
 Closure used to pass the client and the id to the callback that replies to a client's request. More...
 
struct  ClientContext
 Struct used to store the context of a connected client. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log (kind, __VA_ARGS__)
 
#define SET_PEER_FLAG(peer_ctx, mask)   ((peer_ctx->peer_flags) |= (mask))
 Set a peer flag of given peer context.
 
#define check_peer_flag_set(peer_ctx, mask)    ((peer_ctx->peer_flags) & (mask) ? GNUNET_YES : GNUNET_NO)
 Get peer flag of given peer context.
 
#define UNSET_PEER_FLAG(peer_ctx, mask)   ((peer_ctx->peer_flags) &= ~(mask))
 Unset flag of given peer context.
 
#define check_channel_flag_set(channel_flags, mask)    ((*channel_flags) & (mask) ? GNUNET_YES : GNUNET_NO)
 Get channel flag of given channel context.
 
#define unset_channel_flag(channel_flags, mask)   ((*channel_flags) &= ~(mask))
 Unset flag of given channel context.
 
#define HISTOGRAM_FILE_SLOTS   32
 This number determines the number of slots for files that represent histograms.
 
#define SIZE_DUMP_FILE   (HISTOGRAM_FILE_SLOTS * 5) + 1
 The size (in bytes) a file needs to store the histogram.
 

Functions

static void do_round (void *cls)
 Send out PUSHes and PULLs, possibly update #view, samplers.
 
static struct PeerContextget_peer_ctx (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer)
 Get the PeerContext associated with a peer.
 
static int check_peer_known (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer)
 Check whether we have information about the given peer.
 
static struct PeerContextcreate_peer_ctx (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Create a new PeerContext and insert it into the peer map.
 
static struct PeerContextcreate_or_get_peer_ctx (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Create or get a PeerContext.
 
static int check_connected (struct PeerContext *peer_ctx)
 Check whether we have a connection to this peer.
 
static int get_rand_peer_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Iterator function for get_random_peer_from_peermap.
 
static const struct GNUNET_PeerIdentityget_random_peer_from_peermap (struct GNUNET_CONTAINER_MultiPeerMap *valid_peers)
 Get a random peer from peer_map.
 
static int add_valid_peer (const struct GNUNET_PeerIdentity *peer, struct GNUNET_CONTAINER_MultiPeerMap *valid_peers)
 Add a given peer to valid peers.
 
static void remove_pending_message (struct PendingMessage *pending_msg, int cancel)
 Remove a pending message from the respective DLL.
 
static void set_peer_online (struct PeerContext *peer_ctx)
 Set the peer flag to living and call the pending operations on this peer.
 
static void cleanup_destroyed_channel (void *cls, const struct GNUNET_CADET_Channel *channel)
 This is called when a channel is destroyed.
 
static void handle_peer_check (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle a CHECK_LIVE message from another peer.
 
static void handle_peer_push (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle a PUSH message from another peer.
 
static void handle_peer_pull_request (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle PULL REQUEST request message from another peer.
 
static int check_peer_pull_reply (void *cls, const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
 Check whether we sent a corresponding request and whether this reply is the first one.
 
static void handle_peer_pull_reply (void *cls, const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
 Handle PULL REPLY message from another peer.
 
static struct ChannelCtxadd_channel_ctx (struct PeerContext *peer_ctx)
 Allocate memory for a new channel context and insert it into DLL.
 
static void remove_channel_ctx (struct ChannelCtx *channel_ctx)
 Free memory and NULL pointers.
 
struct GNUNET_CADET_Channelget_channel (struct PeerContext *peer_ctx)
 Get the channel of a peer.
 
static struct GNUNET_MQ_Handleget_mq (struct PeerContext *peer_ctx)
 Get the message queue (GNUNET_MQ_Handle) of a specific peer.
 
static struct PendingMessageinsert_pending_message (struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type)
 Add an envelope to a message passed to mq to list of pending messages.
 
static void mq_online_check_successful (void *cls)
 This is called in response to the first message we sent as a online check.
 
static void check_peer_online (struct PeerContext *peer_ctx)
 Issue a check whether peer is online.
 
static int check_operation_scheduled (const struct PeerContext *peer_ctx, const PeerOp peer_op)
 Check whether function of type PeerOp was already scheduled.
 
static void destroy_channel (struct ChannelCtx *channel_ctx)
 Callback for scheduler to destroy a channel.
 
static void destroy_channel_cb (void *cls)
 Destroy a cadet channel.
 
static void schedule_channel_destruction (struct ChannelCtx *channel_ctx)
 Schedule the destruction of a channel for immediately afterwards.
 
static int destroy_peer (struct PeerContext *peer_ctx)
 Remove peer.
 
static int peermap_clear_iterator (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Iterator over hash map entries.
 
static void mq_notify_sent_cb (void *cls)
 This is called once a message is sent.
 
static int store_peer_presistently_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Iterator function for store_valid_peers.
 
static void store_valid_peers (const struct Sub *sub)
 Store the peers currently in #valid_peers to disk.
 
static const struct GNUNET_PeerIdentitys2i_full (const char *string_repr)
 Convert string representation of peer id to peer id.
 
static void restore_valid_peers (const struct Sub *sub)
 Restore the peers on disk to #valid_peers.
 
static void peers_terminate (struct Sub *sub)
 Delete storage of peers that was created with #initialise_peers ()
 
static int valid_peer_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Iterator over #valid_peers hash map entries.
 
static int get_valid_peers (struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, PeersIterator iterator, void *it_cls)
 Get all currently known, valid peer ids.
 
static int insert_peer (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Add peer to known peers.
 
static int check_peer_flag (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags)
 Check whether flags on a peer are set.
 
static int issue_peer_online_check (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Try connecting to a peer to see whether it is online.
 
static int check_removable (const struct PeerContext *peer_ctx)
 Check if peer is removable.
 
static int check_peer_valid (const struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, const struct GNUNET_PeerIdentity *peer)
 Check whether peer is actually a peer.
 
static void indicate_sending_intention (struct PeerContext *peer_ctx)
 Indicate that we want to send to the other peer.
 
static int check_peer_send_intention (const struct PeerContext *peer_ctx)
 Check whether other peer has the intention to send/opened channel towars us.
 
static void * handle_inbound_channel (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
 Handle the channel a peer opens to us.
 
static int check_sending_channel_exists (const struct PeerContext *peer_ctx)
 Check whether a sending channel towards the given peer exists.
 
static int destroy_sending_channel (struct PeerContext *peer_ctx)
 Destroy the send channel of a peer e.g.
 
static void send_message (struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type)
 Send a message to another peer.
 
static int schedule_operation (struct PeerContext *peer_ctx, const PeerOp peer_op, void *cls)
 Schedule a operation on given peer.
 
static void print_peer_list (struct GNUNET_PeerIdentity *list, unsigned int len)
 Print peerlist to log.
 
static void rem_from_list (struct GNUNET_PeerIdentity **peer_list, unsigned int *list_size, const struct GNUNET_PeerIdentity *peer)
 Remove peer from list.
 
static void insert_in_view_op (void *cls, const struct GNUNET_PeerIdentity *peer)
 Insert PeerID in #view.
 
static int insert_in_view (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Insert PeerID in #view.
 
static void send_view (const struct ClientContext *cli_ctx, const struct GNUNET_PeerIdentity *view_array, uint64_t view_size)
 Send view to client.
 
static void send_stream_peers (const struct ClientContext *cli_ctx, uint64_t num_peers, const struct GNUNET_PeerIdentity *peers)
 Send peer from biased stream to client.
 
static void clients_notify_view_update (const struct Sub *sub)
 sends updates to clients that are interested
 
static void clients_notify_stream_peer (const struct Sub *sub, uint64_t num_peers, const struct GNUNET_PeerIdentity *peers)
 sends updates to clients that are interested
 
static void hist_update (const struct GNUNET_PeerIdentity *ids, uint32_t num_peers, void *cls)
 Put random peer from sampler into the view as history update.
 
static void resize_wrapper (struct RPS_Sampler *sampler, uint32_t new_size)
 Wrapper around RPS_sampler_resize()
 
static void send_pull_reply (struct PeerContext *peer_ctx, const struct GNUNET_PeerIdentity *peer_ids, unsigned int num_peer_ids)
 Send a PULL REPLY to peer_id.
 
static void insert_in_pull_map (void *cls, const struct GNUNET_PeerIdentity *peer)
 Insert PeerID in #pull_map.
 
static void insert_in_sampler (void *cls, const struct GNUNET_PeerIdentity *peer)
 Update sampler with given PeerID.
 
static void got_peer (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 This is called on peers from external sources (cadet, peerinfo, ...) If the peer is not known, online check is issued and it is scheduled to be inserted in sampler and view.
 
static int check_sending_channel_needed (const struct PeerContext *peer_ctx)
 Checks if there is a sending channel and if it is needed.
 
static void remove_peer (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 remove peer from our knowledge, the view, push and pull maps and samplers.
 
static void clean_peer (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Remove data that is not needed anymore.
 
struct Subnew_sub (const struct GNUNET_HashCode *hash, uint32_t sampler_size, struct GNUNET_TIME_Relative round_interval)
 Create a new Sub.
 
static void destroy_sub (struct Sub *sub)
 Destroy Sub.
 
void core_init (void *cls, const struct GNUNET_PeerIdentity *my_identity)
 Callback on initialisation of Core.
 
void * core_connects (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
 Callback for core.
 
void core_disconnects (void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
 Callback for core.
 
static void destroy_cli_ctx (struct ClientContext *cli_ctx)
 Destroy the context for a (connected) client.
 
static void adapt_sizes (struct Sub *sub, double logestimate, double std_dev)
 Update sizes in sampler and view on estimate update from nse service.
 
static void nse_callback (void *cls, struct GNUNET_TIME_Absolute timestamp, double logestimate, double std_dev)
 Function called by NSE.
 
static int check_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg)
 This function is called, when the client seeds peers.
 
static void handle_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg)
 Handle seed from the client.
 
static void handle_client_view_request (void *cls, const struct GNUNET_RPS_CS_DEBUG_ViewRequest *msg)
 Handle RPS request from the client.
 
static void handle_client_view_cancel (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle the cancellation of the view updates.
 
static void handle_client_stream_request (void *cls, const struct GNUNET_RPS_CS_DEBUG_StreamRequest *msg)
 Handle RPS request for biased stream from the client.
 
static void handle_client_stream_cancel (void *cls, const struct GNUNET_MessageHeader *msg)
 Handles the cancellation of the stream of biased peer ids.
 
static void handle_client_start_sub (void *cls, const struct GNUNET_RPS_CS_SubStartMessage *msg)
 Create and start a Sub.
 
static void handle_client_stop_sub (void *cls, const struct GNUNET_RPS_CS_SubStopMessage *msg)
 Destroy the Sub.
 
static struct GNUNET_TIME_Relative compute_rand_delay (struct GNUNET_TIME_Relative mean, unsigned int spread)
 Compute a random delay.
 
static void send_pull_request (struct PeerContext *peer_ctx)
 Send single pull request.
 
static void send_push (struct PeerContext *peer_ctx)
 Send single push.
 
void init_peer_cb (void *cls, const struct GNUNET_PeerIdentity *peer, int tunnel, unsigned int n_paths, unsigned int best_path)
 This is called from GNUNET_CADET_get_peers().
 
static int valid_peers_iterator (void *cls, const struct GNUNET_PeerIdentity *peer)
 Iterator function over stored, valid peers.
 
void process_peerinfo_peers (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Iterator over peers from peerinfo.
 
static void shutdown_task (void *cls)
 Task run during shutdown.
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 Handle client connecting to the service.
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
 Callback called when a client disconnected from the service.
 
static void error_cb (void *cls)
 
static void sync_cb (void *cls)
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
 Handle random peer sampling clients.
 
 GNUNET_SERVICE_MAIN (GNUNET_OS_project_data_gnunet(), "rps", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(client_seed, GNUNET_MESSAGE_TYPE_RPS_CS_SEED, struct GNUNET_RPS_CS_SeedMessage, NULL), GNUNET_MQ_hd_fixed_size(client_view_request, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REQUEST, struct GNUNET_RPS_CS_DEBUG_ViewRequest, NULL), GNUNET_MQ_hd_fixed_size(client_view_cancel, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_CANCEL, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(client_stream_request, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REQUEST, struct GNUNET_RPS_CS_DEBUG_StreamRequest, NULL), GNUNET_MQ_hd_fixed_size(client_stream_cancel, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_CANCEL, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(client_start_sub, GNUNET_MESSAGE_TYPE_RPS_CS_SUB_START, struct GNUNET_RPS_CS_SubStartMessage, NULL), GNUNET_MQ_hd_fixed_size(client_stop_sub, GNUNET_MESSAGE_TYPE_RPS_CS_SUB_STOP, struct GNUNET_RPS_CS_SubStopMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro.
 

Variables

static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration.
 
struct GNUNET_STATISTICS_Handlestats
 Handle to the statistics service.
 
struct GNUNET_CADET_Handlecadet_handle
 Handler to CADET.
 
struct GNUNET_CORE_Handlecore_handle
 Handle to CORE.
 
struct GNUNET_CONTAINER_MultiPeerMapmap_single_hop
 PeerMap to keep track of connected peers.
 
static struct GNUNET_PeerIdentity own_identity
 Our own identity.
 
static float alpha
 Percentage of total peer number in the view to send random PUSHes to.
 
static float beta
 Percentage of total peer number in the view to send random PULLs to.
 
static struct GNUNET_NSE_Handlense
 Handler to NSE.
 
static struct GNUNET_PEERSTORE_Handlepeerstore
 Handle to the PEERSTORE service.
 
static struct GNUNET_PEERSTORE_Monitorpeerstore_notify
 Our peerstore notification context.
 
static struct Submsub
 Main Sub.
 
static const uint32_t num_valid_peers_max = UINT32_MAX
 Maximum number of valid peers to keep.
 
struct ClientContextcli_ctx_head
 DLL with all clients currently connected to us.
 
struct ClientContextcli_ctx_tail
 

Detailed Description

rps service implementation

Author
Julius Bünger

Definition in file gnunet-service-rps.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log (kind, __VA_ARGS__)

Definition at line 45 of file gnunet-service-rps.c.

◆ SET_PEER_FLAG

#define SET_PEER_FLAG (   peer_ctx,
  mask 
)    ((peer_ctx->peer_flags) |= (mask))

Set a peer flag of given peer context.

Definition at line 64 of file gnunet-service-rps.c.

◆ check_peer_flag_set

#define check_peer_flag_set (   peer_ctx,
  mask 
)     ((peer_ctx->peer_flags) & (mask) ? GNUNET_YES : GNUNET_NO)

Get peer flag of given peer context.

Definition at line 69 of file gnunet-service-rps.c.

70 : GNUNET_NO)
@ GNUNET_NO

◆ UNSET_PEER_FLAG

#define UNSET_PEER_FLAG (   peer_ctx,
  mask 
)    ((peer_ctx->peer_flags) &= ~(mask))

Unset flag of given peer context.

Definition at line 75 of file gnunet-service-rps.c.

◆ check_channel_flag_set

#define check_channel_flag_set (   channel_flags,
  mask 
)     ((*channel_flags) & (mask) ? GNUNET_YES : GNUNET_NO)

Get channel flag of given channel context.

Definition at line 80 of file gnunet-service-rps.c.

81 : GNUNET_NO)

◆ unset_channel_flag

#define unset_channel_flag (   channel_flags,
  mask 
)    ((*channel_flags) &= ~(mask))

Unset flag of given channel context.

Definition at line 86 of file gnunet-service-rps.c.

◆ HISTOGRAM_FILE_SLOTS

#define HISTOGRAM_FILE_SLOTS   32

This number determines the number of slots for files that represent histograms.

Definition at line 289 of file gnunet-service-rps.c.

◆ SIZE_DUMP_FILE

#define SIZE_DUMP_FILE   (HISTOGRAM_FILE_SLOTS * 5) + 1

The size (in bytes) a file needs to store the histogram.

Per slot: 1 newline, up to 4 chars, Additionally: 1 null termination

Definition at line 297 of file gnunet-service-rps.c.

Function Documentation

◆ do_round()

static void do_round ( void *  cls)
static

Send out PUSHes and PULLs, possibly update #view, samplers.

This is executed regylary.

Parameters
clsClosure - Sub

Definition at line 4293 of file gnunet-service-rps.c.

4294{
4295 unsigned int i;
4296 const struct GNUNET_PeerIdentity *view_array;
4297 unsigned int *permut;
4298 unsigned int a_peers; /* Number of peers we send pushes to */
4299 unsigned int b_peers; /* Number of peers we send pull requests to */
4300 uint32_t first_border;
4301 uint32_t second_border;
4302 struct GNUNET_PeerIdentity peer;
4303 struct GNUNET_PeerIdentity *update_peer;
4304 struct Sub *sub = cls;
4305
4306 sub->num_rounds++;
4308 "Going to execute next round.\n");
4309 if (sub == msub)
4310 {
4311 GNUNET_STATISTICS_update (stats, "# rounds", 1, GNUNET_NO);
4312 }
4313 sub->do_round_task = NULL;
4314#ifdef TO_FILE_FULL
4315 to_file (sub->file_name_view_log,
4316 "___ new round ___");
4317#endif /* TO_FILE_FULL */
4318 view_array = View_get_as_array (sub->view);
4319 for (i = 0; i < View_size (sub->view); i++)
4320 {
4322 "\t%s\n", GNUNET_i2s (&view_array[i]));
4323#ifdef TO_FILE_FULL
4324 to_file (sub->file_name_view_log,
4325 "=%s\t(do round)",
4326 GNUNET_i2s_full (&view_array[i]));
4327#endif /* TO_FILE_FULL */
4328 }
4329
4330
4331 /* Send pushes and pull requests */
4332 if (0 < View_size (sub->view))
4333 {
4335 View_size (sub->view));
4336
4337 /* Send PUSHes */
4338 a_peers = ceil (alpha * View_size (sub->view));
4339
4341 "Going to send pushes to %u (ceil (%f * %u)) peers.\n",
4342 a_peers, alpha, View_size (sub->view));
4343 for (i = 0; i < a_peers; i++)
4344 {
4345 peer = view_array[permut[i]];
4346 // FIXME if this fails schedule/loop this for later
4347 send_push (get_peer_ctx (sub->peer_map, &peer));
4348 }
4349
4350 /* Send PULL requests */
4351 b_peers = ceil (beta * View_size (sub->view));
4352 first_border = a_peers;
4353 second_border = a_peers + b_peers;
4354 if (second_border > View_size (sub->view))
4355 {
4356 first_border = View_size (sub->view) - b_peers;
4357 second_border = View_size (sub->view);
4358 }
4360 "Going to send pulls to %u (ceil (%f * %u)) peers.\n",
4361 b_peers, beta, View_size (sub->view));
4362 for (i = first_border; i < second_border; i++)
4363 {
4364 peer = view_array[permut[i]];
4365 if (GNUNET_NO == check_peer_flag (sub->peer_map,
4366 &peer,
4368 { // FIXME if this fails schedule/loop this for later
4369 send_pull_request (get_peer_ctx (sub->peer_map, &peer));
4370 }
4371 }
4372
4373 GNUNET_free (permut);
4374 permut = NULL;
4375 }
4376
4377
4378 /* Update view */
4379 /* TODO see how many peers are in push-/pull- list! */
4380
4381 if ((CustomPeerMap_size (sub->push_map) <= alpha * sub->view_size_est_need) &&
4382 (0 < CustomPeerMap_size (sub->push_map)) &&
4383 (0 < CustomPeerMap_size (sub->pull_map)))
4384 { /* If conditions for update are fulfilled, update */
4385 LOG (GNUNET_ERROR_TYPE_DEBUG, "Update of the view.\n");
4386
4387 uint32_t final_size;
4388 uint32_t peers_to_clean_size;
4389 struct GNUNET_PeerIdentity *peers_to_clean;
4390
4391 peers_to_clean = NULL;
4392 peers_to_clean_size = 0;
4393 GNUNET_array_grow (peers_to_clean,
4394 peers_to_clean_size,
4395 View_size (sub->view));
4396 GNUNET_memcpy (peers_to_clean,
4397 view_array,
4398 View_size (sub->view) * sizeof(struct GNUNET_PeerIdentity));
4399
4400 /* Seems like recreating is the easiest way of emptying the peermap */
4401 View_clear (sub->view);
4402#ifdef TO_FILE_FULL
4403 to_file (sub->file_name_view_log,
4404 "--- emptied ---");
4405#endif /* TO_FILE_FULL */
4406
4407 first_border = GNUNET_MIN (ceil (alpha * sub->view_size_est_need),
4409 second_border = first_border
4410 + GNUNET_MIN (floor (beta * sub->view_size_est_need),
4412 final_size = second_border
4413 + ceil ((1 - (alpha + beta)) * sub->view_size_est_need);
4415 "first border: %" PRIu32 ", second border: %" PRIu32 ", final size: %"
4416 PRIu32 "\n",
4417 first_border,
4418 second_border,
4419 final_size);
4420
4421 /* Update view with peers received through PUSHes */
4424 for (i = 0; i < first_border; i++)
4425 {
4426 int inserted;
4427 inserted = insert_in_view (sub,
4429 permut[i]));
4430 if (GNUNET_OK == inserted)
4431 {
4433 1,
4435 sub->push_map, permut[i]));
4436 }
4437#ifdef TO_FILE_FULL
4438 to_file (sub->file_name_view_log,
4439 "+%s\t(push list)",
4440 GNUNET_i2s_full (&view_array[i]));
4441#endif /* TO_FILE_FULL */
4442 // TODO change the peer_flags accordingly
4443 }
4444 GNUNET_free (permut);
4445 permut = NULL;
4446
4447 /* Update view with peers received through PULLs */
4450 for (i = first_border; i < second_border; i++)
4451 {
4452 int inserted;
4453 inserted = insert_in_view (sub,
4455 permut[i
4456 -
4457 first_border
4458 ]));
4459 if (GNUNET_OK == inserted)
4460 {
4462 1,
4464 sub->pull_map,
4465 permut[i
4466 - first_border]));
4467 }
4468#ifdef TO_FILE_FULL
4469 to_file (sub->file_name_view_log,
4470 "+%s\t(pull list)",
4471 GNUNET_i2s_full (&view_array[i]));
4472#endif /* TO_FILE_FULL */
4473 // TODO change the peer_flags accordingly
4474 }
4475 GNUNET_free (permut);
4476 permut = NULL;
4477
4478 /* Update view with peers from history */
4480 final_size - second_border,
4482 sub);
4483 // TODO change the peer_flags accordingly
4484
4485 for (i = 0; i < View_size (sub->view); i++)
4486 rem_from_list (&peers_to_clean, &peers_to_clean_size, &view_array[i]);
4487
4488 /* Clean peers that were removed from the view */
4489 for (i = 0; i < peers_to_clean_size; i++)
4490 {
4491#ifdef TO_FILE_FULL
4492 to_file (sub->file_name_view_log,
4493 "-%s",
4494 GNUNET_i2s_full (&peers_to_clean[i]));
4495#endif /* TO_FILE_FULL */
4496 clean_peer (sub, &peers_to_clean[i]);
4497 }
4498
4499 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0);
4501 }
4502 else
4503 {
4504 LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n");
4505 if (sub == msub)
4506 {
4507 GNUNET_STATISTICS_update (stats, "# rounds blocked", 1, GNUNET_NO);
4508 if ((CustomPeerMap_size (sub->push_map) > alpha
4509 * sub->view_size_est_need) &&
4510 ! (0 >= CustomPeerMap_size (sub->pull_map)))
4511 GNUNET_STATISTICS_update (stats, "# rounds blocked - too many pushes",
4512 1, GNUNET_NO);
4513 if ((CustomPeerMap_size (sub->push_map) > alpha
4514 * sub->view_size_est_need) &&
4515 (0 >= CustomPeerMap_size (sub->pull_map)))
4517 "# rounds blocked - too many pushes, no pull replies",
4518 1, GNUNET_NO);
4519 if ((0 >= CustomPeerMap_size (sub->push_map)) &&
4520 ! (0 >= CustomPeerMap_size (sub->pull_map)))
4521 GNUNET_STATISTICS_update (stats, "# rounds blocked - no pushes", 1,
4522 GNUNET_NO);
4523 if ((0 >= CustomPeerMap_size (sub->push_map)) &&
4524 (0 >= CustomPeerMap_size (sub->pull_map)))
4526 "# rounds blocked - no pushes, no pull replies",
4527 1, GNUNET_NO);
4528 if ((0 >= CustomPeerMap_size (sub->pull_map)) &&
4530 * sub->view_size_est_need) &&
4531 (0 >= CustomPeerMap_size (sub->push_map)) )
4532 GNUNET_STATISTICS_update (stats, "# rounds blocked - no pull replies",
4533 1, GNUNET_NO);
4534 }
4535 }
4536 // TODO independent of that also get some peers from CADET_get_peers()?
4538 {
4539 sub->push_recv[CustomPeerMap_size (sub->push_map)]++;
4540 }
4541 else
4542 {
4544 "Push map size too big for histogram (%u, %u)\n",
4547 }
4548 // FIXME check bounds of histogram
4549 sub->push_delta[(int32_t) (CustomPeerMap_size (sub->push_map)
4550 - (alpha * sub->view_size_est_need))
4551 + (HISTOGRAM_FILE_SLOTS / 2)]++;
4552 if (sub == msub)
4553 {
4555 "# peers in push map at end of round",
4557 GNUNET_NO);
4559 "# peers in pull map at end of round",
4561 GNUNET_NO);
4563 "# peers in view at end of round",
4564 View_size (sub->view),
4565 GNUNET_NO);
4567 "# expected pushes",
4569 GNUNET_NO);
4571 "delta expected - received pushes",
4573 * sub->
4574 view_size_est_need),
4575 GNUNET_NO);
4576 }
4577
4579 "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (sub->view%u) = %.2f)\n",
4582 alpha,
4583 View_size (sub->view),
4584 alpha * View_size (sub->view));
4585
4586 /* Update samplers */
4587 for (i = 0; i < CustomPeerMap_size (sub->push_map); i++)
4588 {
4589 update_peer = CustomPeerMap_get_peer_by_index (sub->push_map, i);
4591 "Updating with peer %s from push list\n",
4592 GNUNET_i2s (update_peer));
4593 insert_in_sampler (sub, update_peer);
4594 clean_peer (sub, update_peer); /* This cleans only if it is not in the view */
4595 }
4596
4597 for (i = 0; i < CustomPeerMap_size (sub->pull_map); i++)
4598 {
4600 "Updating with peer %s from pull list\n",
4603 /* This cleans only if it is not in the view */
4605 }
4606
4607
4608 /* Empty push/pull lists */
4611
4612 if (sub == msub)
4613 {
4615 "view size",
4616 View_size (sub->view),
4617 GNUNET_NO);
4618 }
4619
4620 struct GNUNET_TIME_Relative time_next_round;
4621
4622 time_next_round = compute_rand_delay (sub->round_interval, 2);
4623
4624 /* Schedule next round */
4625 sub->do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round,
4626 &do_round, sub);
4627 LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished round\n");
4628}
static void clean_peer(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
Remove data that is not needed anymore.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static struct Sub * msub
Main Sub.
static void send_pull_request(struct PeerContext *peer_ctx)
Send single pull request.
#define HISTOGRAM_FILE_SLOTS
This number determines the number of slots for files that represent histograms.
static void send_push(struct PeerContext *peer_ctx)
Send single push.
static struct GNUNET_TIME_Relative compute_rand_delay(struct GNUNET_TIME_Relative mean, unsigned int spread)
Compute a random delay.
static int check_peer_flag(const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags)
Check whether flags on a peer are set.
static int insert_in_view(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
Insert PeerID in #view.
static float beta
Percentage of total peer number in the view to send random PULLs to.
static float alpha
Percentage of total peer number in the view to send random PUSHes to.
static void clients_notify_view_update(const struct Sub *sub)
sends updates to clients that are interested
static struct PeerContext * get_peer_ctx(const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer)
Get the PeerContext associated with a peer.
static void hist_update(const struct GNUNET_PeerIdentity *ids, uint32_t num_peers, void *cls)
Put random peer from sampler into the view as history update.
#define LOG(kind,...)
static void clients_notify_stream_peer(const struct Sub *sub, uint64_t num_peers, const struct GNUNET_PeerIdentity *peers)
sends updates to clients that are interested
static void rem_from_list(struct GNUNET_PeerIdentity **peer_list, unsigned int *list_size, const struct GNUNET_PeerIdentity *peer)
Remove peer from list.
static void insert_in_sampler(void *cls, const struct GNUNET_PeerIdentity *peer)
Update sampler with given PeerID.
static void do_round(void *cls)
Send out PUSHes and PULLs, possibly update #view, samplers.
unsigned int CustomPeerMap_size(const struct CustomPeerMap *c_peer_map)
Get the size of the custom peer map.
void CustomPeerMap_clear(const struct CustomPeerMap *c_peer_map)
Clear the custom peer map.
struct GNUNET_PeerIdentity * CustomPeerMap_get_peer_by_index(const struct CustomPeerMap *c_peer_map, uint32_t index)
Get a peer by index.
struct RPS_SamplerRequestHandle * RPS_sampler_get_n_rand_peers(struct RPS_Sampler *sampler, uint32_t num_peers, RPS_sampler_n_rand_peers_ready_cb cb, void *cls)
Get n random peers out of the sampled peers.
void View_clear(struct View *view)
Clear the view.
const struct GNUNET_PeerIdentity * View_get_as_array(const struct View *view)
Get the view as an array.
unsigned int View_size(const struct View *view)
Get the size of the view.
unsigned int * GNUNET_CRYPTO_random_permute(enum GNUNET_CRYPTO_Quality mode, unsigned int n)
Get an array with a random permutation of the numbers 0...n-1.
@ GNUNET_CRYPTO_QUALITY_STRONG
High-quality operations are desired.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MIN(a, b)
@ GNUNET_OK
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define to_file(file_name,...)
This function is used to facilitate writing important information to disk.
@ Peers_PULL_REPLY_PENDING
If we are waiting for a reply from that peer (sent a pull request).
Definition rps.h:250
The identity of the host (wraps the signing key of the peer).
Time for relative time used by GNUnet, in microseconds.
One Sub.
struct RPS_Sampler * sampler
Sampler used for the Brahms protocol itself.
uint32_t push_delta[32]
Histogram of deltas between the expected and actual number of received pushes.
unsigned int view_size_est_need
This is the estimate used as view size.
uint32_t push_recv[32]
This array accumulates the number of received pushes per round.
struct CustomPeerMap * pull_map
List to store peers received through pulls temporary.
struct GNUNET_CONTAINER_MultiPeerMap * peer_map
Set of all peers to keep track of them.
uint32_t num_rounds
Counts the executed rounds.
struct GNUNET_SCHEDULER_Task * do_round_task
Identifier for the main task that runs periodically.
struct CustomPeerMap * push_map
List to store peers received through pushes temporary.
struct View * view
The view.
struct GNUNET_TIME_Relative round_interval
Time interval the do_round task runs in.

References alpha, beta, check_peer_flag(), clean_peer(), clients_notify_stream_peer(), clients_notify_view_update(), compute_rand_delay(), CustomPeerMap_clear(), CustomPeerMap_get_peer_by_index(), CustomPeerMap_size(), do_round(), Sub::do_round_task, get_peer_ctx(), GNUNET_array_grow, GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_CRYPTO_random_permute(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_i2s(), GNUNET_i2s_full(), GNUNET_memcpy, GNUNET_MIN, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), hist_update(), HISTOGRAM_FILE_SLOTS, insert_in_sampler(), insert_in_view(), LOG, msub, Sub::num_rounds, Sub::peer_map, Peers_PULL_REPLY_PENDING, Sub::pull_map, Sub::push_delta, Sub::push_map, Sub::push_recv, rem_from_list(), Sub::round_interval, RPS_sampler_get_n_rand_peers(), Sub::sampler, send_pull_request(), send_push(), stats, to_file, Sub::view, View_clear(), View_get_as_array(), View_size(), and Sub::view_size_est_need.

Referenced by do_round(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_relative2s(), and new_sub().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_peer_ctx()

static struct PeerContext * get_peer_ctx ( const struct GNUNET_CONTAINER_MultiPeerMap peer_map,
const struct GNUNET_PeerIdentity peer 
)
static

Get the PeerContext associated with a peer.

Parameters
peer_mapThe peer map containing the context
peerthe peer id
Returns
the PeerContext

Definition at line 617 of file gnunet-service-rps.c.

619{
620 struct PeerContext *ctx;
621 int ret;
622
625 ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer);
626 GNUNET_assert (NULL != ctx);
627 return ctx;
628}
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_FS_Handle * ctx
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL).
@ GNUNET_YES
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Struct used to keep track of other peer's status.

References ctx, GNUNET_assert, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_get(), GNUNET_YES, and ret.

Referenced by check_connected(), check_peer_flag(), clean_peer(), create_or_get_peer_ctx(), do_round(), got_peer(), handle_inbound_channel(), handle_peer_pull_reply(), insert_in_view(), issue_peer_online_check(), peermap_clear_iterator(), and remove_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_peer_known()

static int check_peer_known ( const struct GNUNET_CONTAINER_MultiPeerMap peer_map,
const struct GNUNET_PeerIdentity peer 
)
static

Check whether we have information about the given peer.

FIXME probably deprecated. Make this the new _online.

Parameters
peer_mapThe peer map to check for the existence of peer
peerpeer in question
Returns
GNUNET_YES if peer is known GNUNET_NO if peer is not known

Definition at line 643 of file gnunet-service-rps.c.

645{
646 if (NULL != peer_map)
647 {
648 return GNUNET_CONTAINER_multipeermap_contains (peer_map, peer);
649 }
650 else
651 {
652 return GNUNET_NO;
653 }
654}

References GNUNET_CONTAINER_multipeermap_contains(), and GNUNET_NO.

Referenced by check_connected(), check_peer_flag(), check_sending_channel_exists(), check_sending_channel_needed(), create_or_get_peer_ctx(), create_peer_ctx(), destroy_sending_channel(), handle_peer_pull_reply(), handle_peer_pull_request(), handle_peer_push(), hist_update(), indicate_sending_intention(), insert_peer(), remove_peer(), and schedule_operation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_peer_ctx()

static struct PeerContext * create_peer_ctx ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

Create a new PeerContext and insert it into the peer map.

Parameters
subThe Sub this context belongs to.
peerthe peer to create the PeerContext for
Returns
the PeerContext

Definition at line 666 of file gnunet-service-rps.c.

668{
669 struct PeerContext *ctx;
670 int ret;
671
673
674 ctx = GNUNET_new (struct PeerContext);
675 ctx->peer_id = *peer;
676 ctx->sub = sub;
680 if (sub == msub)
681 {
683 "# known peers",
685 GNUNET_NO);
686 }
687 return ctx;
688}
static int check_peer_known(const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer)
Check whether we have information about the given peer.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct Sub * sub
The Sub this context belongs to.

References check_peer_known(), ctx, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_set(), msub, Sub::peer_map, ret, stats, and PeerContext::sub.

Referenced by create_or_get_peer_ctx(), and insert_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_or_get_peer_ctx()

static struct PeerContext * create_or_get_peer_ctx ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

Create or get a PeerContext.

Parameters
subThe Sub to which the created context belongs to
peerthe peer to get the associated context to
Returns
the context

Definition at line 700 of file gnunet-service-rps.c.

702{
703 if (GNUNET_NO == check_peer_known (sub->peer_map, peer))
704 {
705 return create_peer_ctx (sub, peer);
706 }
707 return get_peer_ctx (sub->peer_map, peer);
708}
static struct PeerContext * create_peer_ctx(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
Create a new PeerContext and insert it into the peer map.

References check_peer_known(), create_peer_ctx(), get_peer_ctx(), GNUNET_NO, Sub::peer_map, and PeerContext::sub.

Referenced by handle_inbound_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_connected()

static int check_connected ( struct PeerContext peer_ctx)
static

Check whether we have a connection to this peer.

Also sets the Peers_ONLINE flag accordingly

Parameters
peer_ctxContext of the peer of which connectivity is to be checked
Returns
GNUNET_YES if we are connected GNUNET_NO otherwise

Definition at line 722 of file gnunet-service-rps.c.

723{
724 /* If we don't know about this peer we don't know whether it's online */
725 if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
726 &peer_ctx->peer_id))
727 {
728 return GNUNET_NO;
729 }
730 /* Get the context */
731 peer_ctx = get_peer_ctx (peer_ctx->sub->peer_map, &peer_ctx->peer_id);
732 /* If we have no channel to this peer we don't know whether it's online */
733 if ((NULL == peer_ctx->send_channel_ctx) &&
734 (NULL == peer_ctx->recv_channel_ctx))
735 {
736 UNSET_PEER_FLAG (peer_ctx, Peers_ONLINE);
737 return GNUNET_NO;
738 }
739 /* Otherwise (if we have a channel, we know that it's online */
740 SET_PEER_FLAG (peer_ctx, Peers_ONLINE);
741 return GNUNET_YES;
742}
#define SET_PEER_FLAG(peer_ctx, mask)
Set a peer flag of given peer context.
#define UNSET_PEER_FLAG(peer_ctx, mask)
Unset flag of given peer context.
@ Peers_ONLINE
We set this bit when we know the peer is online.
Definition rps.h:259
struct ChannelCtx * send_channel_ctx
Channel open to client.
struct ChannelCtx * recv_channel_ctx
Channel open from client.
struct GNUNET_PeerIdentity peer_id
Identity of the peer.

References check_peer_known(), get_peer_ctx(), GNUNET_NO, GNUNET_YES, PeerContext::peer_id, Sub::peer_map, Peers_ONLINE, PeerContext::recv_channel_ctx, PeerContext::send_channel_ctx, SET_PEER_FLAG, PeerContext::sub, and UNSET_PEER_FLAG.

Referenced by destroy_sending_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_rand_peer_iterator()

static int get_rand_peer_iterator ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  value 
)
static

Iterator function for get_random_peer_from_peermap.

Implements GNUNET_CONTAINER_PeerMapIterator. Decreases the index until the index is null. Then returns the current peer.

Parameters
clsthe GetRandPeerIteratorCls containing index and peer
peercurrent peer
valueunused
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 780 of file gnunet-service-rps.c.

783{
784 struct GetRandPeerIteratorCls *iterator_cls = cls;
785
786 (void) value;
787
788 if (0 >= iterator_cls->index)
789 {
790 iterator_cls->peer = peer;
791 return GNUNET_NO;
792 }
793 iterator_cls->index--;
794 return GNUNET_YES;
795}
static char * value
Value of the record to add/remove.
The closure to get_rand_peer_iterator.
uint32_t index
The index of the peer to return.
const struct GNUNET_PeerIdentity * peer
Pointer to peer to return.

References GNUNET_NO, GNUNET_YES, GetRandPeerIteratorCls::index, GetRandPeerIteratorCls::peer, and value.

Referenced by get_random_peer_from_peermap().

Here is the caller graph for this function:

◆ get_random_peer_from_peermap()

static const struct GNUNET_PeerIdentity * get_random_peer_from_peermap ( struct GNUNET_CONTAINER_MultiPeerMap valid_peers)
static

Get a random peer from peer_map.

Parameters
valid_peersPeer map containing valid peers from which to select a random one
Returns
a random peer

Definition at line 807 of file gnunet-service-rps.c.

808{
809 struct GetRandPeerIteratorCls *iterator_cls;
810 const struct GNUNET_PeerIdentity *ret;
811
812 iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls);
815 (
816 valid_peers));
817 (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
819 iterator_cls);
820 ret = iterator_cls->peer;
821 GNUNET_free (iterator_cls);
822 return ret;
823}
static int get_rand_peer_iterator(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Iterator function for get_random_peer_from_peermap.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.

References get_rand_peer_iterator(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_free, GNUNET_new, GetRandPeerIteratorCls::index, GetRandPeerIteratorCls::peer, and ret.

Referenced by add_valid_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_valid_peer()

static int add_valid_peer ( const struct GNUNET_PeerIdentity peer,
struct GNUNET_CONTAINER_MultiPeerMap valid_peers 
)
static

Add a given peer to valid peers.

If valid peers are already num_valid_peers_max, delete a peer previously.

Parameters
peerThe peer that is added to the valid peers.
valid_peersPeer map of valid peers to which to add the peer
Returns
GNUNET_YES if no other peer had to be removed GNUNET_NO otherwise

Definition at line 838 of file gnunet-service-rps.c.

840{
841 const struct GNUNET_PeerIdentity *rand_peer;
842 int ret;
843
844 ret = GNUNET_YES;
845 /* Remove random peers until there is space for a new one */
846 while (num_valid_peers_max <=
848 {
849 rand_peer = get_random_peer_from_peermap (valid_peers);
850 GNUNET_CONTAINER_multipeermap_remove_all (valid_peers, rand_peer);
851 ret = GNUNET_NO;
852 }
853 (void) GNUNET_CONTAINER_multipeermap_put (valid_peers, peer, NULL,
855 if (valid_peers == msub->valid_peers)
856 {
858 "# valid peers",
860 GNUNET_NO);
861 }
862 return ret;
863}
static const struct GNUNET_PeerIdentity * get_random_peer_from_peermap(struct GNUNET_CONTAINER_MultiPeerMap *valid_peers)
Get a random peer from peer_map.
static const uint32_t num_valid_peers_max
Maximum number of valid peers to keep.
int GNUNET_CONTAINER_multipeermap_remove_all(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Remove all entries for the given key from the map.
struct GNUNET_CONTAINER_MultiPeerMap * valid_peers
Hashmap of valid peers.

References get_random_peer_from_peermap(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_remove_all(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_YES, msub, num_valid_peers_max, ret, stats, and Sub::valid_peers.

Referenced by handle_inbound_channel(), mq_online_check_successful(), and restore_valid_peers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_pending_message()

static void remove_pending_message ( struct PendingMessage pending_msg,
int  cancel 
)
static

Remove a pending message from the respective DLL.

Parameters
pending_msgthe pending message to remove
cancelwhether to cancel the pending message, too

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

1093{
1094 struct PeerContext *peer_ctx;
1095
1096 (void) cancel;
1097
1098 peer_ctx = pending_msg->peer_ctx;
1099 GNUNET_assert (NULL != peer_ctx);
1101 peer_ctx->pending_messages_tail,
1102 pending_msg);
1103 // TODO wait for the cadet implementation of message cancellation
1104 // if (GNUNET_YES == cancel)
1105 // {
1106 // GNUNET_MQ_send_cancel (pending_msg->ev);
1107 // }
1108 GNUNET_free (pending_msg);
1109}
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct PendingMessage * pending_messages_tail
struct PendingMessage * pending_messages_head
DLL with all messages that are yet to be sent.
struct PeerContext * peer_ctx
The corresponding context.

References GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, PendingMessage::peer_ctx, PeerContext::pending_messages_head, and PeerContext::pending_messages_tail.

Referenced by destroy_peer(), mq_notify_sent_cb(), mq_online_check_successful(), and set_peer_online().

Here is the caller graph for this function:

◆ set_peer_online()

static void set_peer_online ( struct PeerContext peer_ctx)
static

Set the peer flag to living and call the pending operations on this peer.

Also adds peer to #valid_peers.

Parameters
peer_ctxthe PeerContext of the peer to set online

Definition at line 878 of file gnunet-service-rps.c.

879{
880 struct GNUNET_PeerIdentity *peer;
881 unsigned int i;
882
883 peer = &peer_ctx->peer_id;
885 "Peer %s is online and valid, calling %i pending operations on it\n",
886 GNUNET_i2s (peer),
887 peer_ctx->num_pending_ops);
888
889 if (NULL != peer_ctx->online_check_pending)
890 {
892 "Removing pending online check for peer %s\n",
893 GNUNET_i2s (&peer_ctx->peer_id));
894 // TODO wait until cadet sets mq->cancel_impl
895 // GNUNET_MQ_send_cancel (peer_ctx->online_check_pending->ev);
897 peer_ctx->online_check_pending = NULL;
898 }
899
900 SET_PEER_FLAG (peer_ctx, Peers_ONLINE);
901
902 /* Call pending operations */
903 for (i = 0; i < peer_ctx->num_pending_ops; i++)
904 {
905 peer_ctx->pending_ops[i].op (peer_ctx->pending_ops[i].op_cls, peer);
906 }
907 GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0);
908}
static void remove_pending_message(struct PendingMessage *pending_msg, int cancel)
Remove a pending message from the respective DLL.
struct PeerPendingOp * pending_ops
Array of pending operations on this peer.
struct PendingMessage * online_check_pending
Handle to the callback given to cadet_ntfy_tmt_rdy()
unsigned int num_pending_ops
Number of pending operations.
void * op_cls
Closure.
PeerOp op
Callback.

References GNUNET_array_grow, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_YES, LOG, PeerContext::num_pending_ops, PeerContext::online_check_pending, PeerPendingOp::op, PeerPendingOp::op_cls, PeerContext::peer_id, Peers_ONLINE, PeerContext::pending_ops, remove_pending_message(), and SET_PEER_FLAG.

Referenced by handle_inbound_channel(), and mq_online_check_successful().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_destroyed_channel()

static void cleanup_destroyed_channel ( void *  cls,
const struct GNUNET_CADET_Channel channel 
)
static

This is called when a channel is destroyed.

Removes peer completely from our knowledge if the send_channel was destroyed Otherwise simply delete the recv_channel Also check if the knowledge about this peer is still needed. If not, remove this peer from our knowledge.

Parameters
clsThe closure - Context to the channel
channelThe channel being closed

Definition at line 2836 of file gnunet-service-rps.c.

2838{
2839 struct ChannelCtx *channel_ctx = cls;
2840 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
2841
2842 (void) channel;
2843
2844 channel_ctx->channel = NULL;
2845 if ((NULL != peer_ctx) &&
2846 (peer_ctx->send_channel_ctx == channel_ctx) &&
2848 {
2849 remove_channel_ctx (channel_ctx);
2850 remove_peer (peer_ctx->sub, &peer_ctx->peer_id);
2851 }
2852 else
2853 {
2854 /* We need this if-else construct because we need to make sure the channel
2855 * (context) is cleaned up before removing the peer, but still need to
2856 * compare it while checking the condition */
2857 remove_channel_ctx (channel_ctx);
2858 }
2859}
static int check_sending_channel_needed(const struct PeerContext *peer_ctx)
Checks if there is a sending channel and if it is needed.
static void remove_channel_ctx(struct ChannelCtx *channel_ctx)
Free memory and NULL pointers.
static void remove_peer(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
remove peer from our knowledge, the view, push and pull maps and samplers.
Context for a channel.
struct PeerContext * peer_ctx
The peer context associated with the channel.
struct GNUNET_CADET_Channel * channel
The channel itself.

References ChannelCtx::channel, check_sending_channel_needed(), GNUNET_YES, ChannelCtx::peer_ctx, PeerContext::peer_id, remove_channel_ctx(), remove_peer(), PeerContext::send_channel_ctx, and PeerContext::sub.

Referenced by get_channel(), and new_sub().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_peer_check()

static void handle_peer_check ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handle a CHECK_LIVE message from another peer.

This does nothing. But without calling GNUNET_CADET_receive_done() the channel is blocked for all other communication.

Parameters
clsClosure - Context of channel
msgMessage - unused

Definition at line 3533 of file gnunet-service-rps.c.

3535{
3536 const struct ChannelCtx *channel_ctx = cls;
3537 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3538
3539 (void) msg;
3540
3542 "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer));
3543 if (channel_ctx->peer_ctx->sub == msub)
3544 {
3546 "# pending online checks",
3547 -1,
3548 GNUNET_NO);
3549 }
3550
3551 GNUNET_CADET_receive_done (channel_ctx->channel);
3552}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
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

References ChannelCtx::channel, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_NO, GNUNET_STATISTICS_update(), LOG, msg, msub, ChannelCtx::peer_ctx, PeerContext::peer_id, stats, and PeerContext::sub.

Here is the call graph for this function:

◆ handle_peer_push()

static void handle_peer_push ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handle a PUSH message from another peer.

Check the proof of work and store the PeerID in the temporary list for pushed PeerIDs.

Parameters
clsClosure - Context of channel
msgMessage - unused

Definition at line 3565 of file gnunet-service-rps.c.

3567{
3568 const struct ChannelCtx *channel_ctx = cls;
3569 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3570
3571 (void) msg;
3572
3573 // (check the proof of work (?))
3574
3576 "Received PUSH (%s)\n",
3577 GNUNET_i2s (peer));
3578 if (channel_ctx->peer_ctx->sub == msub)
3579 {
3580 GNUNET_STATISTICS_update (stats, "# push message received", 1, GNUNET_NO);
3581 if ((NULL != map_single_hop) &&
3583 peer)))
3584 {
3586 "# push message received (multi-hop peer)",
3587 1,
3588 GNUNET_NO);
3589 }
3590 }
3591
3592 #if ENABLE_MALICIOUS
3593 struct AttackedPeer *tmp_att_peer;
3594
3595 if ((1 == mal_type) ||
3596 (3 == mal_type))
3597 { /* Try to maximise representation */
3598 tmp_att_peer = GNUNET_new (struct AttackedPeer);
3599 tmp_att_peer->peer_id = *peer;
3600 if (NULL == att_peer_set)
3603 peer))
3604 {
3605 GNUNET_CONTAINER_DLL_insert (att_peers_head,
3606 att_peers_tail,
3607 tmp_att_peer);
3608 add_peer_array_to_set (peer, 1, att_peer_set);
3609 }
3610 else
3611 {
3612 GNUNET_free (tmp_att_peer);
3613 }
3614 }
3615
3616
3617 else if (2 == mal_type)
3618 {
3619 /* We attack one single well-known peer - simply ignore */
3620 }
3621 #endif /* ENABLE_MALICIOUS */
3622
3623 /* Add the sending peer to the push_map */
3624 CustomPeerMap_put (channel_ctx->peer_ctx->sub->push_map, peer);
3625
3627 &channel_ctx->peer_ctx->peer_id));
3628 GNUNET_CADET_receive_done (channel_ctx->channel);
3629}
struct GNUNET_CONTAINER_MultiPeerMap * map_single_hop
PeerMap to keep track of connected peers.
int CustomPeerMap_put(const struct CustomPeerMap *c_peer_map, const struct GNUNET_PeerIdentity *peer)
Insert peer into the custom peer map.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.

References ChannelCtx::channel, check_peer_known(), CustomPeerMap_put(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, map_single_hop, msg, msub, ChannelCtx::peer_ctx, PeerContext::peer_id, Sub::peer_map, Sub::push_map, stats, and PeerContext::sub.

Here is the call graph for this function:

◆ handle_peer_pull_request()

static void handle_peer_pull_request ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handle PULL REQUEST request message from another peer.

Reply with the view of PeerIDs.

Parameters
clsClosure - Context of channel
msgMessage - unused

Definition at line 3641 of file gnunet-service-rps.c.

3643{
3644 const struct ChannelCtx *channel_ctx = cls;
3645 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
3646 const struct GNUNET_PeerIdentity *peer = &peer_ctx->peer_id;
3647 const struct GNUNET_PeerIdentity *view_array;
3648
3649 (void) msg;
3650
3651 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (
3652 peer));
3653 if (peer_ctx->sub == msub)
3654 {
3656 "# pull request message received",
3657 1,
3658 GNUNET_NO);
3659 if ((NULL != map_single_hop) &&
3661 &peer_ctx->peer_id
3662 )))
3663 {
3665 "# pull request message received (multi-hop peer)",
3666 1,
3667 GNUNET_NO);
3668 }
3669 }
3670
3671 #if ENABLE_MALICIOUS
3672 if ((1 == mal_type)
3673 || (3 == mal_type))
3674 { /* Try to maximise representation */
3675 send_pull_reply (peer_ctx, mal_peers, num_mal_peers);
3676 }
3677
3678 else if (2 == mal_type)
3679 { /* Try to partition network */
3680 if (0 == GNUNET_memcmp (&attacked_peer, peer))
3681 {
3682 send_pull_reply (peer_ctx, mal_peers, num_mal_peers);
3683 }
3684 }
3685 #endif /* ENABLE_MALICIOUS */
3686
3688 &channel_ctx->peer_ctx->peer_id));
3689 GNUNET_CADET_receive_done (channel_ctx->channel);
3690 view_array = View_get_as_array (channel_ctx->peer_ctx->sub->view);
3691 send_pull_reply (peer_ctx,
3692 view_array,
3693 View_size (channel_ctx->peer_ctx->sub->view));
3694}
static void send_pull_reply(struct PeerContext *peer_ctx, const struct GNUNET_PeerIdentity *peer_ids, unsigned int num_peer_ids)
Send a PULL REPLY to peer_id.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.

References ChannelCtx::channel, check_peer_known(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_memcmp, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, map_single_hop, msg, msub, ChannelCtx::peer_ctx, PeerContext::peer_id, Sub::peer_map, send_pull_reply(), stats, PeerContext::sub, Sub::view, View_get_as_array(), and View_size().

Here is the call graph for this function:

◆ check_peer_pull_reply()

static int check_peer_pull_reply ( void *  cls,
const struct GNUNET_RPS_P2P_PullReplyMessage msg 
)
static

Check whether we sent a corresponding request and whether this reply is the first one.

Parameters
clsClosure - Context of channel
msgMessage containing the replied peers

Definition at line 3705 of file gnunet-service-rps.c.

3707{
3708 struct ChannelCtx *channel_ctx = cls;
3709 struct PeerContext *sender_ctx = channel_ctx->peer_ctx;
3710
3711 if (sizeof(struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->header.size))
3712 {
3713 GNUNET_break_op (0);
3714 return GNUNET_SYSERR;
3715 }
3716
3717 if ((ntohs (msg->header.size) - sizeof(struct
3719 / sizeof(struct GNUNET_PeerIdentity) != ntohl (msg->num_peers))
3720 {
3722 "message says it sends %" PRIu32 " peers, have space for %lu peers\n",
3723 ntohl (msg->num_peers),
3724 (ntohs (msg->header.size) - sizeof(struct
3726 / sizeof(struct GNUNET_PeerIdentity));
3727 GNUNET_break_op (0);
3728 return GNUNET_SYSERR;
3729 }
3730
3731 if (GNUNET_YES != check_peer_flag (sender_ctx->sub->peer_map,
3732 &sender_ctx->peer_id,
3734 {
3736 "Received a pull reply from a peer (%s) we didn't request one from!\n",
3737 GNUNET_i2s (&sender_ctx->peer_id));
3738 if (sender_ctx->sub == msub)
3739 {
3741 "# unrequested pull replies",
3742 1,
3743 GNUNET_NO);
3744 }
3745 }
3746 return GNUNET_OK;
3747}
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_ERROR
P2P Message to send PeerIDs to other peer.
Definition rps.h:44

References check_peer_flag(), GNUNET_break_op, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, LOG, msg, msub, ChannelCtx::peer_ctx, PeerContext::peer_id, Sub::peer_map, Peers_PULL_REPLY_PENDING, GNUNET_MessageHeader::size, stats, and PeerContext::sub.

Here is the call graph for this function:

◆ handle_peer_pull_reply()

static void handle_peer_pull_reply ( void *  cls,
const struct GNUNET_RPS_P2P_PullReplyMessage msg 
)
static

Handle PULL REPLY message from another peer.

Parameters
clsClosure
msgThe message header

Definition at line 3757 of file gnunet-service-rps.c.

3759{
3760 const struct ChannelCtx *channel_ctx = cls;
3761 const struct GNUNET_PeerIdentity *sender = &channel_ctx->peer_ctx->peer_id;
3762 const struct GNUNET_PeerIdentity *peers;
3763 struct Sub *sub = channel_ctx->peer_ctx->sub;
3764 uint32_t i;
3765
3766#if ENABLE_MALICIOUS
3767 struct AttackedPeer *tmp_att_peer;
3768#endif /* ENABLE_MALICIOUS */
3769
3770 sub->pull_delays[sub->num_rounds - channel_ctx->peer_ctx->round_pull_req]++;
3771 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REPLY (%s)\n", GNUNET_i2s (
3772 sender));
3773 if (channel_ctx->peer_ctx->sub == msub)
3774 {
3776 "# pull reply messages received",
3777 1,
3778 GNUNET_NO);
3779 if ((NULL != map_single_hop) &&
3781 &channel_ctx->
3782 peer_ctx->peer_id)
3783 ) )
3784 {
3786 "# pull reply messages received (multi-hop peer)",
3787 1,
3788 GNUNET_NO);
3789 }
3790 }
3791
3792 #if ENABLE_MALICIOUS
3793 // We shouldn't even receive pull replies as we're not sending
3794 if (2 == mal_type)
3795 {
3796 }
3797 #endif /* ENABLE_MALICIOUS */
3798
3799 /* Do actual logic */
3800 peers = (const struct GNUNET_PeerIdentity *) &msg[1];
3801
3803 "PULL REPLY received, got following %u peers:\n",
3804 ntohl (msg->num_peers));
3805
3806 for (i = 0; i < ntohl (msg->num_peers); i++)
3807 {
3809 "%u. %s\n",
3810 i,
3811 GNUNET_i2s (&peers[i]));
3812
3813 #if ENABLE_MALICIOUS
3814 if ((NULL != att_peer_set) &&
3815 ((1 == mal_type) || (3 == mal_type) ))
3816 { /* Add attacked peer to local list */
3817 // TODO check if we sent a request and this was the first reply
3819 &peers[i]))
3821 &peers[i])) )
3822 {
3823 tmp_att_peer = GNUNET_new (struct AttackedPeer);
3824 tmp_att_peer->peer_id = peers[i];
3825 GNUNET_CONTAINER_DLL_insert (att_peers_head,
3826 att_peers_tail,
3827 tmp_att_peer);
3828 add_peer_array_to_set (&peers[i], 1, att_peer_set);
3829 }
3830 continue;
3831 }
3832 #endif /* ENABLE_MALICIOUS */
3833 /* Make sure we 'know' about this peer */
3834 (void) insert_peer (channel_ctx->peer_ctx->sub,
3835 &peers[i]);
3836
3837 if (GNUNET_YES == check_peer_valid (channel_ctx->peer_ctx->sub->valid_peers,
3838 &peers[i]))
3839 {
3840 CustomPeerMap_put (channel_ctx->peer_ctx->sub->pull_map,
3841 &peers[i]);
3842 }
3843 else
3844 {
3845 schedule_operation (channel_ctx->peer_ctx,
3847 channel_ctx->peer_ctx->sub); /* cls */
3848 (void) issue_peer_online_check (channel_ctx->peer_ctx->sub,
3849 &peers[i]);
3850 }
3851 }
3852
3854 sender),
3856 clean_peer (channel_ctx->peer_ctx->sub,
3857 sender);
3858
3860 sender));
3861 GNUNET_CADET_receive_done (channel_ctx->channel);
3862}
struct GNUNET_CONTAINER_MultiPeerMap * peers
Map from PIDs to struct CadetPeer entries.
static void insert_in_pull_map(void *cls, const struct GNUNET_PeerIdentity *peer)
Insert PeerID in #pull_map.
static int issue_peer_online_check(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
Try connecting to a peer to see whether it is online.
static int insert_peer(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
Add peer to known peers.
static int schedule_operation(struct PeerContext *peer_ctx, const PeerOp peer_op, void *cls)
Schedule a operation on given peer.
static int check_peer_valid(const struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, const struct GNUNET_PeerIdentity *peer)
Check whether peer is actually a peer.
uint32_t round_pull_req
This is pobably followed by 'statistical' data (when we first saw it, how did we get its ID,...
uint32_t pull_delays[32]
Number of pull replies with this delay measured in rounds.

References ChannelCtx::channel, check_peer_known(), check_peer_valid(), clean_peer(), CustomPeerMap_put(), get_peer_ctx(), GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, insert_in_pull_map(), insert_peer(), issue_peer_online_check(), LOG, map_single_hop, msg, msub, Sub::num_rounds, ChannelCtx::peer_ctx, PeerContext::peer_id, Sub::peer_map, peers, Peers_PULL_REPLY_PENDING, Sub::pull_delays, Sub::pull_map, PeerContext::round_pull_req, schedule_operation(), stats, PeerContext::sub, UNSET_PEER_FLAG, and Sub::valid_peers.

Here is the call graph for this function:

◆ add_channel_ctx()

static struct ChannelCtx * add_channel_ctx ( struct PeerContext peer_ctx)
static

Allocate memory for a new channel context and insert it into DLL.

Parameters
peer_ctxcontext of the according peer
Returns
The channel context

Definition at line 946 of file gnunet-service-rps.c.

947{
948 struct ChannelCtx *channel_ctx;
949
950 channel_ctx = GNUNET_new (struct ChannelCtx);
951 channel_ctx->peer_ctx = peer_ctx;
952 return channel_ctx;
953}

References GNUNET_new, and ChannelCtx::peer_ctx.

Referenced by get_channel(), and handle_inbound_channel().

Here is the caller graph for this function:

◆ remove_channel_ctx()

static void remove_channel_ctx ( struct ChannelCtx channel_ctx)
static

Free memory and NULL pointers.

Parameters
channel_ctxThe channel context.

Definition at line 962 of file gnunet-service-rps.c.

963{
964 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
965
966 if (NULL != channel_ctx->destruction_task)
967 {
969 channel_ctx->destruction_task = NULL;
970 }
971
972 if (NULL == peer_ctx)
973 return;
974 if (channel_ctx == peer_ctx->send_channel_ctx)
975 {
976 peer_ctx->send_channel_ctx = NULL;
977 peer_ctx->mq = NULL;
978 }
979 else if (channel_ctx == peer_ctx->recv_channel_ctx)
980 {
981 peer_ctx->recv_channel_ctx = NULL;
982 }
983 GNUNET_free (channel_ctx);
984}
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * destruction_task
When channel destruction needs to be delayed (because it is called from within the cadet routine of a...
struct GNUNET_MQ_Handle * mq
Message queue open to client.

References ChannelCtx::destruction_task, GNUNET_free, GNUNET_SCHEDULER_cancel(), PeerContext::mq, ChannelCtx::peer_ctx, PeerContext::recv_channel_ctx, and PeerContext::send_channel_ctx.

Referenced by cleanup_destroyed_channel(), and destroy_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_channel()

struct GNUNET_CADET_Channel * get_channel ( struct PeerContext peer_ctx)

Get the channel of a peer.

If not existing, create.

Parameters
peer_ctxContext of the peer of which to get the channel
Returns
the GNUNET_CADET_Channel used to send data to peer_ctx

Definition at line 994 of file gnunet-service-rps.c.

995{
996 /* There exists a copy-paste-clone in run() */
997 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
998 GNUNET_MQ_hd_fixed_size (peer_check,
1000 struct GNUNET_MessageHeader,
1001 NULL),
1002 GNUNET_MQ_hd_fixed_size (peer_push,
1004 struct GNUNET_MessageHeader,
1005 NULL),
1006 GNUNET_MQ_hd_fixed_size (peer_pull_request,
1008 struct GNUNET_MessageHeader,
1009 NULL),
1010 GNUNET_MQ_hd_var_size (peer_pull_reply,
1013 NULL),
1015 };
1016
1017
1018 if (NULL == peer_ctx->send_channel_ctx)
1019 {
1021 "Trying to establish channel to peer %s\n",
1022 GNUNET_i2s (&peer_ctx->peer_id));
1023 peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx);
1024 peer_ctx->send_channel_ctx->channel =
1026 peer_ctx->send_channel_ctx, /* context */
1027 &peer_ctx->peer_id,
1028 &peer_ctx->sub->hash,
1029 NULL, /* WindowSize handler */
1030 &cleanup_destroyed_channel, /* Disconnect handler */
1031 cadet_handlers);
1032 }
1033 GNUNET_assert (NULL != peer_ctx->send_channel_ctx);
1034 GNUNET_assert (NULL != peer_ctx->send_channel_ctx->channel);
1035 return peer_ctx->send_channel_ctx->channel;
1036}
struct GNUNET_CADET_Handle * cadet_handle
Handler to CADET.
static struct ChannelCtx * add_channel_ctx(struct PeerContext *peer_ctx)
Allocate memory for a new channel context and insert it into DLL.
static void cleanup_destroyed_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
This is called when a channel is destroyed.
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition cadet_api.c:1030
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE
RPS check liveliness message to check liveliness of other peer.
#define GNUNET_MESSAGE_TYPE_RPS_PP_PUSH
RPS PUSH message to push own ID to another peer.
#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY
RPS PULL REPLY message which contains the view of the other peer.
#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST
RPS PULL REQUEST message to request the local view of another peer.
Message handler for a specific message type.
Header for all communications.
struct GNUNET_HashCode hash
Hash of the shared value that defines Subs.

References add_channel_ctx(), cadet_handle, ChannelCtx::channel, cleanup_destroyed_channel(), GNUNET_assert, GNUNET_CADET_channel_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, Sub::hash, LOG, PeerContext::peer_id, PeerContext::send_channel_ctx, and PeerContext::sub.

Referenced by get_mq(), and indicate_sending_intention().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mq()

static struct GNUNET_MQ_Handle * get_mq ( struct PeerContext peer_ctx)
static

Get the message queue (GNUNET_MQ_Handle) of a specific peer.

If we already have a message queue open to this client, simply return it, otherwise create one.

Parameters
peer_ctxContext of the peer of which to get the mq
Returns
the GNUNET_MQ_Handle

Definition at line 1049 of file gnunet-service-rps.c.

1050{
1051 if (NULL == peer_ctx->mq)
1052 {
1053 peer_ctx->mq = GNUNET_CADET_get_mq (get_channel (peer_ctx));
1054 }
1055 return peer_ctx->mq;
1056}
struct GNUNET_CADET_Channel * get_channel(struct PeerContext *peer_ctx)
Get the channel of a peer.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition cadet_api.c:1081

References get_channel(), GNUNET_CADET_get_mq(), and PeerContext::mq.

Referenced by check_peer_online(), and send_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_pending_message()

static struct PendingMessage * insert_pending_message ( struct PeerContext peer_ctx,
struct GNUNET_MQ_Envelope ev,
const char *  type 
)
static

Add an envelope to a message passed to mq to list of pending messages.

Parameters
peer_ctxContext of the peer for which to insert the envelope
evenvelope to the message
typetype of the message to be sent
Returns
pointer to pending message

Definition at line 1068 of file gnunet-service-rps.c.

1071{
1072 struct PendingMessage *pending_msg;
1073
1074 pending_msg = GNUNET_new (struct PendingMessage);
1075 pending_msg->ev = ev;
1076 pending_msg->peer_ctx = peer_ctx;
1077 pending_msg->type = type;
1080 pending_msg);
1081 return pending_msg;
1082}
static uint32_t type
Type string converted to DNS type value.
List containing all messages that are yet to be send.
const char * type
The message type.
struct GNUNET_MQ_Envelope * ev
The envelope to the corresponding message.

References PendingMessage::ev, GNUNET_CONTAINER_DLL_insert, GNUNET_new, PendingMessage::peer_ctx, PeerContext::pending_messages_head, PeerContext::pending_messages_tail, type, and PendingMessage::type.

Referenced by check_peer_online(), and send_message().

Here is the caller graph for this function:

◆ mq_online_check_successful()

static void mq_online_check_successful ( void *  cls)
static

This is called in response to the first message we sent as a online check.

Parameters
clsPeerContext of peer with pending online check

Definition at line 1119 of file gnunet-service-rps.c.

1120{
1121 struct PeerContext *peer_ctx = cls;
1122
1123 if (NULL != peer_ctx->online_check_pending)
1124 {
1126 "Online check for peer %s was successful\n",
1127 GNUNET_i2s (&peer_ctx->peer_id));
1129 peer_ctx->online_check_pending = NULL;
1130 set_peer_online (peer_ctx);
1131 (void) add_valid_peer (&peer_ctx->peer_id, peer_ctx->sub->valid_peers);
1132 }
1133}
static int add_valid_peer(const struct GNUNET_PeerIdentity *peer, struct GNUNET_CONTAINER_MultiPeerMap *valid_peers)
Add a given peer to valid peers.
static void set_peer_online(struct PeerContext *peer_ctx)
Set the peer flag to living and call the pending operations on this peer.

References add_valid_peer(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_YES, LOG, PeerContext::online_check_pending, PeerContext::peer_id, remove_pending_message(), set_peer_online(), PeerContext::sub, and Sub::valid_peers.

Referenced by check_peer_online().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_peer_online()

static void check_peer_online ( struct PeerContext peer_ctx)
static

Issue a check whether peer is online.

Parameters
peer_ctxthe context of the peer

Definition at line 1142 of file gnunet-service-rps.c.

1143{
1145 "Get informed about peer %s getting online\n",
1146 GNUNET_i2s (&peer_ctx->peer_id));
1147
1148 struct GNUNET_MQ_Handle *mq;
1149 struct GNUNET_MQ_Envelope *ev;
1150
1152 peer_ctx->online_check_pending =
1153 insert_pending_message (peer_ctx, ev, "Check online");
1154 mq = get_mq (peer_ctx);
1157 peer_ctx);
1158 GNUNET_MQ_send (mq, ev);
1159 if (peer_ctx->sub == msub)
1160 {
1162 "# pending online checks",
1163 1,
1164 GNUNET_NO);
1165 }
1166}
static void mq_online_check_successful(void *cls)
This is called in response to the first message we sent as a online check.
static struct GNUNET_MQ_Handle * get_mq(struct PeerContext *peer_ctx)
Get the message queue (GNUNET_MQ_Handle) of a specific peer.
static struct PendingMessage * insert_pending_message(struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type)
Add an envelope to a message passed to mq to list of pending messages.
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.
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition mq.c:655
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Handle to a message queue.
Definition mq.c:87

References get_mq(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, GNUNET_MQ_msg_header, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), insert_pending_message(), LOG, mq, mq_online_check_successful(), msub, PeerContext::online_check_pending, PeerContext::peer_id, stats, and PeerContext::sub.

Referenced by issue_peer_online_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_operation_scheduled()

static int check_operation_scheduled ( const struct PeerContext peer_ctx,
const PeerOp  peer_op 
)
static

Check whether function of type PeerOp was already scheduled.

The array with pending operations will probably never grow really big, so iterating over it should be ok.

Parameters
peer_ctxContext of the peer to check for the operation
peer_opthe operation (PeerOp) on the peer
Returns
GNUNET_YES if this operation is scheduled on that peer GNUNET_NO otherwise

Definition at line 1182 of file gnunet-service-rps.c.

1184{
1185 unsigned int i;
1186
1187 for (i = 0; i < peer_ctx->num_pending_ops; i++)
1188 if (peer_op == peer_ctx->pending_ops[i].op)
1189 return GNUNET_YES;
1190 return GNUNET_NO;
1191}

References GNUNET_NO, GNUNET_YES, PeerContext::num_pending_ops, PeerPendingOp::op, and PeerContext::pending_ops.

Referenced by schedule_operation().

Here is the caller graph for this function:

◆ destroy_channel()

static void destroy_channel ( struct ChannelCtx channel_ctx)
static

Callback for scheduler to destroy a channel.

Parameters
channel_ctxContext of the channel

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

1201{
1202 struct GNUNET_CADET_Channel *channel;
1203
1204 if (NULL != channel_ctx->destruction_task)
1205 {
1207 channel_ctx->destruction_task = NULL;
1208 }
1209 GNUNET_assert (channel_ctx->channel != NULL);
1210 channel = channel_ctx->channel;
1211 channel_ctx->channel = NULL;
1213 remove_channel_ctx (channel_ctx);
1214}
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition cadet_api.c:833
Opaque handle to a channel.
Definition cadet.h:116

References ChannelCtx::channel, ChannelCtx::destruction_task, GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_SCHEDULER_cancel(), and remove_channel_ctx().

Referenced by destroy_channel_cb(), destroy_sending_channel(), and handle_inbound_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_channel_cb()

static void destroy_channel_cb ( void *  cls)
static

Destroy a cadet channel.

This satisfies the function signature of GNUNET_SCHEDULER_TaskCallback.

Parameters
cls

Definition at line 1225 of file gnunet-service-rps.c.

1226{
1227 struct ChannelCtx *channel_ctx = cls;
1228
1229 channel_ctx->destruction_task = NULL;
1230 destroy_channel (channel_ctx);
1231}
static void destroy_channel(struct ChannelCtx *channel_ctx)
Callback for scheduler to destroy a channel.

References destroy_channel(), and ChannelCtx::destruction_task.

Referenced by schedule_channel_destruction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_channel_destruction()

static void schedule_channel_destruction ( struct ChannelCtx channel_ctx)
static

Schedule the destruction of a channel for immediately afterwards.

In case a channel is to be destroyed from within the callback to the destruction of another channel (send channel), we cannot call GNUNET_CADET_channel_destroy directly, but need to use this scheduling construction.

Parameters
channel_ctxchannel to be destroyed.

Definition at line 1245 of file gnunet-service-rps.c.

1246{
1247 GNUNET_assert (NULL ==
1248 channel_ctx->destruction_task);
1249 GNUNET_assert (NULL !=
1250 channel_ctx->channel);
1251 channel_ctx->destruction_task =
1253 channel_ctx);
1254}
static void destroy_channel_cb(void *cls)
Destroy a cadet channel.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310

References ChannelCtx::channel, destroy_channel_cb(), ChannelCtx::destruction_task, GNUNET_assert, and GNUNET_SCHEDULER_add_now().

Referenced by destroy_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_peer()

static int destroy_peer ( struct PeerContext peer_ctx)
static

Remove peer.

  • 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
Parameters
peer_ctxContext of the peer to be destroyed
Returns
GNUNET_YES if peer was removed GNUNET_NO otherwise

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

1272{
1273 GNUNET_assert (NULL != peer_ctx);
1274 GNUNET_assert (NULL != peer_ctx->sub->peer_map);
1275 if (GNUNET_NO ==
1277 &peer_ctx->peer_id))
1278 {
1279 return GNUNET_NO;
1280 }
1281 SET_PEER_FLAG (peer_ctx, Peers_TO_DESTROY);
1283 "Going to remove peer %s\n",
1284 GNUNET_i2s (&peer_ctx->peer_id));
1285 UNSET_PEER_FLAG (peer_ctx, Peers_ONLINE);
1286
1287 /* Clear list of pending operations */
1288 // TODO this probably leaks memory
1289 // ('only' the cls to the function. Not sure what to do with it)
1290 GNUNET_array_grow (peer_ctx->pending_ops,
1291 peer_ctx->num_pending_ops,
1292 0);
1293 /* Remove all pending messages */
1294 while (NULL != peer_ctx->pending_messages_head)
1295 {
1297 "Removing unsent %s\n",
1298 peer_ctx->pending_messages_head->type);
1299 /* Cancel pending message, too */
1300 if ((NULL != peer_ctx->online_check_pending) &&
1301 (0 == memcmp (peer_ctx->pending_messages_head,
1302 peer_ctx->online_check_pending,
1303 sizeof(struct PendingMessage))))
1304 {
1305 peer_ctx->online_check_pending = NULL;
1306 if (peer_ctx->sub == msub)
1307 {
1309 "# pending online checks",
1310 -1,
1311 GNUNET_NO);
1312 }
1313 }
1315 GNUNET_YES);
1316 }
1317
1318 /* If we are still waiting for notification whether this peer is online
1319 * cancel the according task */
1320 if (NULL != peer_ctx->online_check_pending)
1321 {
1323 "Removing pending online check for peer %s\n",
1324 GNUNET_i2s (&peer_ctx->peer_id));
1325 // TODO wait until cadet sets mq->cancel_impl
1326 // GNUNET_MQ_send_cancel (peer_ctx->online_check_pending->ev);
1328 GNUNET_YES);
1329 peer_ctx->online_check_pending = NULL;
1330 }
1331
1332 if (NULL != peer_ctx->send_channel_ctx)
1333 {
1334 /* This is possibly called from within channel destruction */
1335 peer_ctx->send_channel_ctx->peer_ctx = NULL;
1337 peer_ctx->send_channel_ctx = NULL;
1338 peer_ctx->mq = NULL;
1339 }
1340 if (NULL != peer_ctx->recv_channel_ctx)
1341 {
1342 /* This is possibly called from within channel destruction */
1343 peer_ctx->recv_channel_ctx->peer_ctx = NULL;
1345 peer_ctx->recv_channel_ctx = NULL;
1346 }
1347
1348 if (GNUNET_YES !=
1350 &peer_ctx->peer_id))
1351 {
1353 "removing peer from peer_ctx->sub->peer_map failed\n");
1354 }
1355 if (peer_ctx->sub == msub)
1356 {
1358 "# known peers",
1360 peer_ctx->sub->peer_map),
1361 GNUNET_NO);
1362 }
1363 GNUNET_free (peer_ctx);
1364 return GNUNET_YES;
1365}
static void schedule_channel_destruction(struct ChannelCtx *channel_ctx)
Schedule the destruction of a channel for immediately afterwards.
#define GNUNET_log(kind,...)
@ Peers_TO_DESTROY
We set this bit when we are going to destroy the channel to this peer.
Definition rps.h:266

References GNUNET_array_grow, GNUNET_assert, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_remove_all(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_YES, LOG, PeerContext::mq, msub, PeerContext::num_pending_ops, PeerContext::online_check_pending, ChannelCtx::peer_ctx, PeerContext::peer_id, Sub::peer_map, Peers_ONLINE, Peers_TO_DESTROY, PeerContext::pending_messages_head, PeerContext::pending_ops, PeerContext::recv_channel_ctx, remove_pending_message(), schedule_channel_destruction(), PeerContext::send_channel_ctx, SET_PEER_FLAG, stats, PeerContext::sub, PendingMessage::type, and UNSET_PEER_FLAG.

Referenced by peermap_clear_iterator(), and remove_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ peermap_clear_iterator()

static int peermap_clear_iterator ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Iterator over hash map entries.

Deletes all contexts of peers.

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

Definition at line 1378 of file gnunet-service-rps.c.

1381{
1382 struct Sub *sub = cls;
1383
1384 (void) value;
1385
1387 return GNUNET_YES;
1388}
struct GNUNET_HashCode key
The key used in the DHT.
static int destroy_peer(struct PeerContext *peer_ctx)
Remove peer.

References destroy_peer(), get_peer_ctx(), GNUNET_YES, key, Sub::peer_map, and value.

Referenced by peers_terminate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_notify_sent_cb()

static void mq_notify_sent_cb ( void *  cls)
static

This is called once a message is sent.

Removes the pending message

Parameters
clstype of the message that was sent

Definition at line 1399 of file gnunet-service-rps.c.

1400{
1401 struct PendingMessage *pending_msg = (struct PendingMessage *) cls;
1402
1404 "%s was sent.\n",
1405 pending_msg->type);
1406 if (pending_msg->peer_ctx->sub == msub)
1407 {
1408 if (0 == strncmp ("PULL REPLY", pending_msg->type, 10))
1409 GNUNET_STATISTICS_update (stats, "# pull replies sent", 1, GNUNET_NO);
1410 if (0 == strncmp ("PULL REQUEST", pending_msg->type, 12))
1411 GNUNET_STATISTICS_update (stats, "# pull requests sent", 1, GNUNET_NO);
1412 if (0 == strncmp ("PUSH", pending_msg->type, 4))
1413 GNUNET_STATISTICS_update (stats, "# pushes sent", 1, GNUNET_NO);
1414 if ((0 == strncmp ("PULL REQUEST", pending_msg->type, 12)) &&
1415 (NULL != map_single_hop) &&
1417 &pending_msg->
1419 ) )
1421 "# pull requests sent (multi-hop peer)",
1422 1,
1423 GNUNET_NO);
1424 }
1425 /* Do not cancel message */
1426 remove_pending_message (pending_msg, GNUNET_NO);
1427}

References GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, map_single_hop, msub, PendingMessage::peer_ctx, PeerContext::peer_id, remove_pending_message(), stats, PeerContext::sub, and PendingMessage::type.

Referenced by send_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_peer_presistently_iterator()

static int store_peer_presistently_iterator ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  value 
)
static

Iterator function for store_valid_peers.

Implements GNUNET_CONTAINER_PeerMapIterator. Writes single peer to disk.

Parameters
clsthe file handle to write to.
peercurrent peer
valueunused
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 1445 of file gnunet-service-rps.c.

1448{
1449 const struct GNUNET_DISK_FileHandle *fh = cls;
1450 char peer_string[128];
1451 int size;
1452 ssize_t ret;
1453
1454 (void) value;
1455
1456 if (NULL == peer)
1457 {
1458 return GNUNET_YES;
1459 }
1460 size = GNUNET_snprintf (peer_string,
1461 sizeof(peer_string),
1462 "%s\n",
1463 GNUNET_i2s_full (peer));
1464 GNUNET_assert (53 == size);
1466 peer_string,
1467 size);
1468 GNUNET_assert (size == ret);
1469 return GNUNET_YES;
1470}
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition disk.c:745
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
static unsigned int size
Size of the "table".
Definition peer.c:68
Handle used to access files (and pipes).

References GNUNET_assert, GNUNET_DISK_file_write(), GNUNET_i2s_full(), GNUNET_snprintf(), GNUNET_YES, ret, size, and value.

Referenced by store_valid_peers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_valid_peers()

static void store_valid_peers ( const struct Sub sub)
static

Store the peers currently in #valid_peers to disk.

Parameters
subSub for which to store the valid peers

Definition at line 1479 of file gnunet-service-rps.c.

1480{
1481 struct GNUNET_DISK_FileHandle *fh;
1482 uint32_t number_written_peers;
1483 int ret;
1484
1485 if (0 == strncmp ("DISABLE", sub->filename_valid_peers, 7))
1486 {
1487 return;
1488 }
1489
1491 if (GNUNET_SYSERR == ret)
1492 {
1494 "Not able to create directory for file `%s'\n",
1496 GNUNET_break (0);
1497 }
1498 else if (GNUNET_NO == ret)
1499 {
1501 "Directory for file `%s' exists but is not writable for us\n",
1503 GNUNET_break (0);
1504 }
1510 if (NULL == fh)
1511 {
1513 "Not able to write valid peers to file `%s'\n",
1515 return;
1516 }
1518 "Writing %u valid peers to disk\n",
1520 number_written_peers =
1523 fh);
1525 GNUNET_assert (number_written_peers ==
1527}
static int store_peer_presistently_iterator(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Iterator function for store_valid_peers.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition disk.c:1308
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1386
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:664
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
char * filename_valid_peers
Filename of the file that stores the valid peers persistently.

References Sub::filename_valid_peers, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_DISK_directory_create_for_file(), GNUNET_DISK_file_close(), GNUNET_DISK_file_open(), GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, LOG, ret, store_peer_presistently_iterator(), and Sub::valid_peers.

Referenced by peers_terminate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ s2i_full()

static const struct GNUNET_PeerIdentity * s2i_full ( const char *  string_repr)
static

Convert string representation of peer id to peer id.

Counterpart to GNUNET_i2s_full.

Parameters
string_reprThe string representation of the peer id
Returns
The peer id

Definition at line 1540 of file gnunet-service-rps.c.

1541{
1542 struct GNUNET_PeerIdentity *peer;
1543 size_t len;
1544 int ret;
1545
1546 peer = GNUNET_new (struct GNUNET_PeerIdentity);
1547 len = strlen (string_repr);
1548 if (52 > len)
1549 {
1551 "Not able to convert string representation of PeerID to PeerID\n"
1552 "String representation: %s (len %lu) - too short\n",
1553 string_repr,
1554 len);
1555 GNUNET_break (0);
1556 }
1557 else if (52 < len)
1558 {
1559 len = 52;
1560 }
1562 len,
1563 &peer->public_key);
1564 if (GNUNET_OK != ret)
1565 {
1567 "Not able to convert string representation of PeerID to PeerID\n"
1568 "String representation: %s\n",
1569 string_repr);
1570 GNUNET_break (0);
1571 }
1572 return peer;
1573}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition crypto_ecc.c:361
struct GNUNET_CRYPTO_EddsaPublicKey public_key

References GNUNET_break, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_ERROR_TYPE_WARNING, GNUNET_new, GNUNET_OK, LOG, GNUNET_PeerIdentity::public_key, and ret.

Referenced by restore_valid_peers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restore_valid_peers()

static void restore_valid_peers ( const struct Sub sub)
static

Restore the peers on disk to #valid_peers.

Parameters
subSub for which to restore the valid peers

Definition at line 1582 of file gnunet-service-rps.c.

1583{
1584 off_t file_size;
1585 uint32_t num_peers;
1586 struct GNUNET_DISK_FileHandle *fh;
1587 char *buf;
1588 ssize_t size_read;
1589 char *iter_buf;
1590 char *str_repr;
1591 const struct GNUNET_PeerIdentity *peer;
1592
1593 if (0 == strncmp ("DISABLE", sub->filename_valid_peers, 7))
1594 {
1595 return;
1596 }
1597
1599 {
1600 return;
1601 }
1605 GNUNET_assert (NULL != fh);
1607 num_peers = file_size / 53;
1608 buf = GNUNET_malloc (file_size);
1609 size_read = GNUNET_DISK_file_read (fh, buf, file_size);
1610 GNUNET_assert (size_read == file_size);
1612 "Restoring %" PRIu32 " peers from file `%s'\n",
1613 num_peers,
1615 for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53)
1616 {
1617 str_repr = GNUNET_strndup (iter_buf, 53);
1618 peer = s2i_full (str_repr);
1619 GNUNET_free (str_repr);
1620 add_valid_peer (peer, sub->valid_peers);
1622 "Restored valid peer %s from disk\n",
1623 GNUNET_i2s_full (peer));
1624 }
1625 iter_buf = NULL;
1626 GNUNET_free (buf);
1628 "num_peers: %" PRIu32 ", _size (sub->valid_peers): %u\n",
1629 num_peers,
1632 {
1634 "Number of restored peers does not match file size. Have probably duplicates.\n");
1635 }
1638 "Restored %u valid peers from disk\n",
1640}
static const struct GNUNET_PeerIdentity * s2i_full(const char *string_repr)
Convert string representation of peer id to peer id.
static unsigned int num_peers
Number of peers.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition disk.c:557
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:704
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition disk.c:206
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_malloc(size)
Wrapper around malloc.

References add_valid_peer(), Sub::filename_valid_peers, GNUNET_assert, GNUNET_CONTAINER_multipeermap_size(), GNUNET_DISK_file_close(), GNUNET_DISK_file_handle_size(), GNUNET_DISK_file_open(), GNUNET_DISK_file_read(), GNUNET_DISK_file_test(), GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_i2s_full(), GNUNET_malloc, GNUNET_OK, GNUNET_strndup, LOG, num_peers, s2i_full(), and Sub::valid_peers.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ peers_terminate()

static void peers_terminate ( struct Sub sub)
static

Delete storage of peers that was created with #initialise_peers ()

Parameters
subSub for which the storage is deleted

Definition at line 1649 of file gnunet-service-rps.c.

1650{
1651 if (GNUNET_SYSERR ==
1654 sub))
1655 {
1657 "Iteration destroying peers was aborted.\n");
1658 }
1660 sub->peer_map = NULL;
1661 store_valid_peers (sub);
1663 sub->filename_valid_peers = NULL;
1665 sub->valid_peers = NULL;
1666}
static void store_valid_peers(const struct Sub *sub)
Store the peers currently in #valid_peers to disk.
static int peermap_clear_iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.

References Sub::filename_valid_peers, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_SYSERR, LOG, Sub::peer_map, peermap_clear_iterator(), store_valid_peers(), and Sub::valid_peers.

Referenced by destroy_sub().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ valid_peer_iterator()

static int valid_peer_iterator ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  value 
)
static

Iterator over #valid_peers hash map entries.

Parameters
clsClosure that contains iterator function and closure
peercurrent peer id
valuevalue in the hash map - unused
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 1680 of file gnunet-service-rps.c.

1683{
1684 struct PeersIteratorCls *it_cls = cls;
1685
1686 (void) value;
1687
1688 return it_cls->iterator (it_cls->cls, peer);
1689}
Closure to valid_peer_iterator.
PeersIterator iterator
Iterator function.
void * cls
Closure to iterator.

References PeersIteratorCls::cls, PeersIteratorCls::iterator, and value.

Referenced by get_valid_peers().

Here is the caller graph for this function:

◆ get_valid_peers()

static int get_valid_peers ( struct GNUNET_CONTAINER_MultiPeerMap valid_peers,
PeersIterator  iterator,
void *  it_cls 
)
static

Get all currently known, valid peer ids.

Parameters
valid_peersPeer map containing the valid peers in question
iteratorfunction to call on each peer id
it_clsextra argument to iterator
Returns
the number of key value pairs processed, GNUNET_SYSERR if it aborted iteration

Definition at line 1702 of file gnunet-service-rps.c.

1705{
1706 struct PeersIteratorCls *cls;
1707 int ret;
1708
1709 cls = GNUNET_new (struct PeersIteratorCls);
1710 cls->iterator = iterator;
1711 cls->cls = it_cls;
1714 cls);
1715 GNUNET_free (cls);
1716 return ret;
1717}
static int valid_peer_iterator(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Iterator over #valid_peers hash map entries.

References PeersIteratorCls::cls, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_free, GNUNET_new, PeersIteratorCls::iterator, ret, and valid_peer_iterator().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_peer()

static int insert_peer ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

Add peer to known peers.

This function is called on new peer_ids from 'external' sources (client seed, cadet get_peers(), ...)

Parameters
subSub with the peer map that the peer will be added to
peerthe new GNUNET_PeerIdentity
Returns
GNUNET_YES if peer was inserted GNUNET_NO otherwise

Definition at line 1733 of file gnunet-service-rps.c.

1735{
1736 if (GNUNET_YES == check_peer_known (sub->peer_map, peer))
1737 {
1738 return GNUNET_NO; /* We already know this peer - nothing to do */
1739 }
1740 (void) create_peer_ctx (sub, peer);
1741 return GNUNET_YES;
1742}

References check_peer_known(), create_peer_ctx(), GNUNET_NO, GNUNET_YES, and Sub::peer_map.

Referenced by handle_peer_pull_reply(), and issue_peer_online_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_peer_flag()

static int check_peer_flag ( const struct GNUNET_CONTAINER_MultiPeerMap peer_map,
const struct GNUNET_PeerIdentity peer,
enum Peers_PeerFlags  flags 
)
static

Check whether flags on a peer are set.

Parameters
peer_mapPeer map that is expected to contain the peer
peerthe peer to check the flag of
flagsthe flags to check
Returns
GNUNET_SYSERR if peer is not known GNUNET_YES if all given flags are set GNUNET_NO otherwise

Definition at line 1757 of file gnunet-service-rps.c.

1760{
1761 struct PeerContext *peer_ctx;
1762
1763 if (GNUNET_NO == check_peer_known (peer_map, peer))
1764 {
1765 return GNUNET_SYSERR;
1766 }
1767 peer_ctx = get_peer_ctx (peer_map, peer);
1768 return check_peer_flag_set (peer_ctx, flags);
1769}
#define check_peer_flag_set(peer_ctx, mask)
Get peer flag of given peer context.

References check_peer_flag_set, check_peer_known(), get_peer_ctx(), GNUNET_NO, and GNUNET_SYSERR.

Referenced by check_peer_pull_reply(), check_sending_channel_needed(), do_round(), insert_in_view(), issue_peer_online_check(), and send_pull_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ issue_peer_online_check()

static int issue_peer_online_check ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

Try connecting to a peer to see whether it is online.

If not known yet, insert into known peers

Parameters
subSub which would contain the peer
peerthe peer whose online is to be checked
Returns
GNUNET_YES if the check was issued GNUNET_NO otherwise

Definition at line 1783 of file gnunet-service-rps.c.

1785{
1786 struct PeerContext *peer_ctx;
1787
1788 (void) insert_peer (sub, peer); // TODO even needed?
1789 peer_ctx = get_peer_ctx (sub->peer_map, peer);
1790 if ((GNUNET_NO == check_peer_flag (sub->peer_map, peer, Peers_ONLINE)) &&
1791 (NULL == peer_ctx->online_check_pending))
1792 {
1793 check_peer_online (peer_ctx);
1794 return GNUNET_YES;
1795 }
1796 return GNUNET_NO;
1797}
static void check_peer_online(struct PeerContext *peer_ctx)
Issue a check whether peer is online.

References check_peer_flag(), check_peer_online(), get_peer_ctx(), GNUNET_NO, GNUNET_YES, insert_peer(), PeerContext::online_check_pending, Sub::peer_map, Peers_ONLINE, and PeerContext::sub.

Referenced by got_peer(), handle_peer_pull_reply(), insert_in_sampler(), and insert_in_view().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_removable()

static int check_removable ( const struct PeerContext peer_ctx)
static

Check if peer is removable.

Check if

  • a recv channel exists
  • there are pending messages
  • there is no pending pull reply
Parameters
peer_ctxContext of the peer in question
Returns
GNUNET_YES if peer is removable GNUNET_NO if peer is NOT removable GNUNET_SYSERR if peer is not known

Definition at line 1814 of file gnunet-service-rps.c.

1815{
1817 peer_ctx->sub->peer_map,
1818 &peer_ctx->peer_id))
1819 {
1820 return GNUNET_SYSERR;
1821 }
1822
1823 if ((NULL != peer_ctx->recv_channel_ctx) ||
1824 (NULL != peer_ctx->pending_messages_head) ||
1826 {
1827 return GNUNET_NO;
1828 }
1829 return GNUNET_YES;
1830}

References check_peer_flag_set, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, PeerContext::peer_id, Sub::peer_map, Peers_PULL_REPLY_PENDING, PeerContext::pending_messages_head, PeerContext::recv_channel_ctx, and PeerContext::sub.

Referenced by clean_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_peer_valid()

static int check_peer_valid ( const struct GNUNET_CONTAINER_MultiPeerMap valid_peers,
const struct GNUNET_PeerIdentity peer 
)
static

Check whether peer is actually a peer.

A valid peer is a peer that we know exists eg. we were connected to once.

Parameters
valid_peersPeer map that would contain the peer
peerpeer in question
Returns
GNUNET_YES if peer is valid GNUNET_NO if peer is not valid

Definition at line 1845 of file gnunet-service-rps.c.

1847{
1848 return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer);
1849}

References GNUNET_CONTAINER_multipeermap_contains().

Referenced by handle_peer_pull_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ indicate_sending_intention()

static void indicate_sending_intention ( struct PeerContext peer_ctx)
static

Indicate that we want to send to the other peer.

This establishes a sending channel

Parameters
peer_ctxContext of the target peer

Definition at line 1860 of file gnunet-service-rps.c.

1861{
1863 &peer_ctx->peer_id));
1864 (void) get_channel (peer_ctx);
1865}

References check_peer_known(), get_channel(), GNUNET_assert, GNUNET_YES, PeerContext::peer_id, Sub::peer_map, and PeerContext::sub.

Referenced by insert_in_view().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_peer_send_intention()

static int check_peer_send_intention ( const struct PeerContext peer_ctx)
static

Check whether other peer has the intention to send/opened channel towars us.

Parameters
peer_ctxContext of the peer in question
Returns
GNUNET_YES if peer has the intention to send GNUNET_NO otherwise

Definition at line 1878 of file gnunet-service-rps.c.

1879{
1880 if (NULL != peer_ctx->recv_channel_ctx)
1881 {
1882 return GNUNET_YES;
1883 }
1884 return GNUNET_NO;
1885}

References GNUNET_NO, GNUNET_YES, and PeerContext::recv_channel_ctx.

Referenced by clean_peer(), and handle_inbound_channel().

Here is the caller graph for this function:

◆ handle_inbound_channel()

static void * handle_inbound_channel ( void *  cls,
struct GNUNET_CADET_Channel channel,
const struct GNUNET_PeerIdentity initiator 
)
static

Handle the channel a peer opens to us.

Parameters
clsThe closure - Sub
channelThe channel the peer wants to establish
initiatorThe peer's peer ID
Returns
initial channel context for the channel (can be NULL – that's not an error)

Definition at line 1899 of file gnunet-service-rps.c.

1902{
1903 struct PeerContext *peer_ctx;
1904 struct ChannelCtx *channel_ctx;
1905 struct Sub *sub = cls;
1906
1908 "New channel was established to us (Peer %s).\n",
1909 GNUNET_i2s (initiator));
1910 GNUNET_assert (NULL != channel); /* according to cadet API */
1911 /* Make sure we 'know' about this peer */
1912 peer_ctx = create_or_get_peer_ctx (sub, initiator);
1913 set_peer_online (peer_ctx);
1914 (void) add_valid_peer (&peer_ctx->peer_id, peer_ctx->sub->valid_peers);
1915 channel_ctx = add_channel_ctx (peer_ctx);
1916 channel_ctx->channel = channel;
1917 /* We only accept one incoming channel per peer */
1919 initiator)))
1920 {
1922 "Already got one receive channel. Destroying old one.\n");
1923 GNUNET_break_op (0);
1925 peer_ctx->recv_channel_ctx = channel_ctx;
1926 /* return the channel context */
1927 return channel_ctx;
1928 }
1929 peer_ctx->recv_channel_ctx = channel_ctx;
1930 return channel_ctx;
1931}
static struct PeerContext * create_or_get_peer_ctx(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
Create or get a PeerContext.
static int check_peer_send_intention(const struct PeerContext *peer_ctx)
Check whether other peer has the intention to send/opened channel towars us.

References add_channel_ctx(), add_valid_peer(), ChannelCtx::channel, check_peer_send_intention(), create_or_get_peer_ctx(), destroy_channel(), get_peer_ctx(), GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_YES, LOG, PeerContext::peer_id, Sub::peer_map, PeerContext::recv_channel_ctx, set_peer_online(), PeerContext::sub, and Sub::valid_peers.

Referenced by new_sub().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_sending_channel_exists()

static int check_sending_channel_exists ( const struct PeerContext peer_ctx)
static

Check whether a sending channel towards the given peer exists.

Parameters
peer_ctxContext of the peer in question
Returns
GNUNET_YES if a sending channel towards that peer exists GNUNET_NO otherwise

Definition at line 1943 of file gnunet-service-rps.c.

1944{
1945 if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
1946 &peer_ctx->peer_id))
1947 { /* If no such peer exists, there is no channel */
1948 return GNUNET_NO;
1949 }
1950 if (NULL == peer_ctx->send_channel_ctx)
1951 {
1952 return GNUNET_NO;
1953 }
1954 return GNUNET_YES;
1955}

References check_peer_known(), GNUNET_NO, GNUNET_YES, PeerContext::peer_id, Sub::peer_map, PeerContext::send_channel_ctx, and PeerContext::sub.

Referenced by check_sending_channel_needed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_sending_channel()

static int destroy_sending_channel ( struct PeerContext peer_ctx)
static

Destroy the send channel of a peer e.g.

stop indicating a sending intention to another peer

Parameters
peer_ctxContext to the peer
Returns
GNUNET_YES if channel was destroyed GNUNET_NO otherwise

Definition at line 1967 of file gnunet-service-rps.c.

1968{
1969 if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
1970 &peer_ctx->peer_id))
1971 {
1972 return GNUNET_NO;
1973 }
1974 if (NULL != peer_ctx->send_channel_ctx)
1975 {
1977 (void) check_connected (peer_ctx);
1978 return GNUNET_YES;
1979 }
1980 return GNUNET_NO;
1981}
static int check_connected(struct PeerContext *peer_ctx)
Check whether we have a connection to this peer.

References check_connected(), check_peer_known(), destroy_channel(), GNUNET_NO, GNUNET_YES, PeerContext::peer_id, Sub::peer_map, PeerContext::send_channel_ctx, and PeerContext::sub.

Referenced by clean_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_message()

static void send_message ( struct PeerContext peer_ctx,
struct GNUNET_MQ_Envelope ev,
const char *  type 
)
static

Send a message to another peer.

Keeps track about pending messages so they can be properly removed when the peer is destroyed.

Parameters
peer_ctxContext of the peer to which the message is to be sent
evenvelope of the message
typetype of the message

Definition at line 1995 of file gnunet-service-rps.c.

1998{
1999 struct PendingMessage *pending_msg;
2000 struct GNUNET_MQ_Handle *mq;
2001
2003 "Sending message to %s of type %s\n",
2004 GNUNET_i2s (&peer_ctx->peer_id),
2005 type);
2006 pending_msg = insert_pending_message (peer_ctx, ev, type);
2007 mq = get_mq (peer_ctx);
2010 pending_msg);
2011 GNUNET_MQ_send (mq, ev);
2012}
static void mq_notify_sent_cb(void *cls)
This is called once a message is sent.

References get_mq(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), insert_pending_message(), mq, mq_notify_sent_cb(), PeerContext::peer_id, and type.

Referenced by send_message_to_room(), send_pull_reply(), send_pull_request(), and send_push().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_operation()

static int schedule_operation ( struct PeerContext peer_ctx,
const PeerOp  peer_op,
void *  cls 
)
static

Schedule a operation on given peer.

Avoids scheduling an operation twice.

Parameters
peer_ctxContext of the peer for which to schedule the operation
peer_opthe operation to schedule
clsClosure to peer_op
Returns
GNUNET_YES if the operation was scheduled GNUNET_NO otherwise

Definition at line 2028 of file gnunet-service-rps.c.

2031{
2032 struct PeerPendingOp pending_op;
2033
2035 &peer_ctx->peer_id));
2036
2037 // TODO if ONLINE execute immediately
2038
2039 if (GNUNET_NO == check_operation_scheduled (peer_ctx, peer_op))
2040 {
2041 pending_op.op = peer_op;
2042 pending_op.op_cls = cls;
2044 peer_ctx->num_pending_ops,
2045 pending_op);
2046 return GNUNET_YES;
2047 }
2048 return GNUNET_NO;
2049}
static int check_operation_scheduled(const struct PeerContext *peer_ctx, const PeerOp peer_op)
Check whether function of type PeerOp was already scheduled.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
Pending operation on peer consisting of callback and closure.

References check_operation_scheduled(), check_peer_known(), GNUNET_array_append, GNUNET_assert, GNUNET_NO, GNUNET_YES, PeerContext::num_pending_ops, PeerPendingOp::op, PeerPendingOp::op_cls, PeerContext::peer_id, Sub::peer_map, PeerContext::pending_ops, and PeerContext::sub.

Referenced by got_peer(), handle_peer_pull_reply(), and insert_in_view().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_peer_list()

static void print_peer_list ( struct GNUNET_PeerIdentity list,
unsigned int  len 
)
static

Print peerlist to log.

Definition at line 2148 of file gnunet-service-rps.c.

2150{
2151 unsigned int i;
2152
2154 "Printing peer list of length %u at %p:\n",
2155 len,
2156 list);
2157 for (i = 0; i < len; i++)
2158 {
2160 "%u. peer: %s\n",
2161 i, GNUNET_i2s (&list[i]));
2162 }
2163}
static int list
Set if we should print a list of currently running services.
Definition gnunet-arm.c:68

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), list, and LOG.

Referenced by handle_client_seed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rem_from_list()

static void rem_from_list ( struct GNUNET_PeerIdentity **  peer_list,
unsigned int *  list_size,
const struct GNUNET_PeerIdentity peer 
)
static

Remove peer from list.

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

2173{
2174 unsigned int i;
2175 struct GNUNET_PeerIdentity *tmp;
2176
2177 tmp = *peer_list;
2178
2180 "Removing peer %s from list at %p\n",
2181 GNUNET_i2s (peer),
2182 tmp);
2183
2184 for (i = 0; i < *list_size; i++)
2185 {
2186 if (0 == GNUNET_memcmp (&tmp[i], peer))
2187 {
2188 if (i < *list_size - 1)
2189 { /* Not at the last entry -- shift peers left */
2190 memmove (&tmp[i], &tmp[i + 1],
2191 ((*list_size) - i - 1) * sizeof(struct GNUNET_PeerIdentity));
2192 }
2193 /* Remove last entry (should be now useless PeerID) */
2194 GNUNET_array_grow (tmp, *list_size, (*list_size) - 1);
2195 }
2196 }
2197 *peer_list = tmp;
2198}

References GNUNET_array_grow, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_memcmp, and LOG.

Referenced by do_round().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_in_view_op()

static void insert_in_view_op ( void *  cls,
const struct GNUNET_PeerIdentity peer 
)
static

Insert PeerID in #view.

Called once we know a peer is online. Implements PeerOp

Returns
GNUNET_OK if peer was actually inserted GNUNET_NO if peer was not inserted

Called once we know a peer is online. Implements PeerOp

Parameters
clsClosure - Sub with view to insert peer into
peerthe peer to insert

Definition at line 2598 of file gnunet-service-rps.c.

2600{
2601 struct Sub *sub = cls;
2602 int inserted;
2603
2604 inserted = insert_in_view (sub, peer);
2605 if (GNUNET_OK == inserted)
2606 {
2607 clients_notify_stream_peer (sub, 1, peer);
2608 }
2609}

References clients_notify_stream_peer(), GNUNET_OK, and insert_in_view().

Referenced by got_peer(), and insert_in_view().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_in_view()

static int insert_in_view ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

Insert PeerID in #view.

Called once we know a peer is online.

Parameters
subSub in with the view to insert in
peerthe peer to insert
Returns
GNUNET_OK if peer was actually inserted GNUNET_NO if peer was not inserted

Definition at line 2226 of file gnunet-service-rps.c.

2228{
2229 struct PeerContext *peer_ctx;
2230 int online;
2231 int ret;
2232
2233 online = check_peer_flag (sub->peer_map, peer, Peers_ONLINE);
2234 peer_ctx = get_peer_ctx (sub->peer_map, peer); // TODO indirection needed?
2235 if ((GNUNET_NO == online) ||
2236 (GNUNET_SYSERR == online)) /* peer is not even known */
2237 {
2238 (void) issue_peer_online_check (sub, peer);
2239 (void) schedule_operation (peer_ctx, insert_in_view_op, sub);
2240 return GNUNET_NO;
2241 }
2242 /* Open channel towards peer to keep connection open */
2243 indicate_sending_intention (peer_ctx);
2244 ret = View_put (sub->view, peer);
2245 if (peer_ctx->sub == msub)
2246 {
2248 "view size",
2249 View_size (peer_ctx->sub->view),
2250 GNUNET_NO);
2251 }
2252 return ret;
2253}
static void insert_in_view_op(void *cls, const struct GNUNET_PeerIdentity *peer)
Insert PeerID in #view.
static void indicate_sending_intention(struct PeerContext *peer_ctx)
Indicate that we want to send to the other peer.
int View_put(struct View *view, const struct GNUNET_PeerIdentity *peer)
Insert peer into the view.

References check_peer_flag(), get_peer_ctx(), GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_SYSERR, indicate_sending_intention(), insert_in_view_op(), issue_peer_online_check(), msub, Sub::peer_map, Peers_ONLINE, ret, schedule_operation(), stats, PeerContext::sub, Sub::view, View_put(), and View_size().

Referenced by do_round(), hist_update(), and insert_in_view_op().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_view()

static void send_view ( const struct ClientContext cli_ctx,
const struct GNUNET_PeerIdentity view_array,
uint64_t  view_size 
)
static

Send view to client.

Parameters
cli_ctxthe context of the client
view_arraythe peerids of the view as array (can be empty)
view_sizethe size of the view array (can be 0)

Definition at line 2264 of file gnunet-service-rps.c.

2267{
2268 struct GNUNET_MQ_Envelope *ev;
2269 struct GNUNET_RPS_CS_DEBUG_ViewReply *out_msg;
2270 struct Sub *sub;
2271
2272 if (NULL == view_array)
2273 {
2274 if (NULL == cli_ctx->sub)
2275 sub = msub;
2276 else
2277 sub = cli_ctx->sub;
2278 view_size = View_size (sub->view);
2279 view_array = View_get_as_array (sub->view);
2280 }
2281
2282 ev = GNUNET_MQ_msg_extra (out_msg,
2283 view_size * sizeof(struct GNUNET_PeerIdentity),
2285 out_msg->num_peers = htonl (view_size);
2286
2287 GNUNET_memcpy (&out_msg[1],
2288 view_array,
2289 view_size * sizeof(struct GNUNET_PeerIdentity));
2290 GNUNET_MQ_send (cli_ctx->mq, ev);
2291}
#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_RPS_CS_DEBUG_VIEW_REPLY
Send update of the view.
struct Sub * sub
The Sub this context belongs to.
struct GNUNET_MQ_Handle * mq
The message queue to communicate with the client.
Message from service to client containing current update of view.
Definition rps.h:186
uint64_t num_peers
Number of peers in the view.
Definition rps.h:200

References GNUNET_memcpy, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REPLY, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), ClientContext::mq, msub, GNUNET_RPS_CS_DEBUG_ViewReply::num_peers, ClientContext::sub, Sub::view, View_get_as_array(), and View_size().

Referenced by clients_notify_view_update(), and handle_client_view_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_stream_peers()

static void send_stream_peers ( const struct ClientContext cli_ctx,
uint64_t  num_peers,
const struct GNUNET_PeerIdentity peers 
)
static

Send peer from biased stream to client.

TODO merge with send_view, parameterise

Parameters
cli_ctxthe context of the client
view_arraythe peerids of the view as array (can be empty)
view_sizethe size of the view array (can be 0)

Definition at line 2304 of file gnunet-service-rps.c.

2307{
2308 struct GNUNET_MQ_Envelope *ev;
2309 struct GNUNET_RPS_CS_DEBUG_StreamReply *out_msg;
2310
2311 GNUNET_assert (NULL != peers);
2312
2313 ev = GNUNET_MQ_msg_extra (out_msg,
2314 num_peers * sizeof(struct GNUNET_PeerIdentity),
2316 out_msg->num_peers = htonl (num_peers);
2317
2318 GNUNET_memcpy (&out_msg[1],
2319 peers,
2320 num_peers * sizeof(struct GNUNET_PeerIdentity));
2321 GNUNET_MQ_send (cli_ctx->mq, ev);
2322}
#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REPLY
Send peer of biased stream.
Message from service to client containing peer from biased stream.
Definition rps.h:220
uint64_t num_peers
Number of peers.
Definition rps.h:229

References GNUNET_assert, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REPLY, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), ClientContext::mq, GNUNET_RPS_CS_DEBUG_StreamReply::num_peers, num_peers, and peers.

Referenced by clients_notify_stream_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clients_notify_view_update()

static void clients_notify_view_update ( const struct Sub sub)
static

sends updates to clients that are interested

Parameters
subSub for which to notify clients

Definition at line 2331 of file gnunet-service-rps.c.

2332{
2333 struct ClientContext *cli_ctx_iter;
2334 uint64_t num_peers;
2335 const struct GNUNET_PeerIdentity *view_array;
2336
2337 num_peers = View_size (sub->view);
2338 view_array = View_get_as_array (sub->view);
2339 /* check size of view is small enough */
2341 {
2343 "View is too big to send\n");
2344 return;
2345 }
2346
2347 for (cli_ctx_iter = cli_ctx_head;
2348 NULL != cli_ctx_iter;
2349 cli_ctx_iter = cli_ctx_iter->next)
2350 {
2351 if (1 < cli_ctx_iter->view_updates_left)
2352 {
2353 /* Client wants to receive limited amount of updates */
2354 cli_ctx_iter->view_updates_left -= 1;
2355 }
2356 else if (1 == cli_ctx_iter->view_updates_left)
2357 {
2358 /* Last update of view for client */
2359 cli_ctx_iter->view_updates_left = -1;
2360 }
2361 else if (0 > cli_ctx_iter->view_updates_left)
2362 {
2363 /* Client is not interested in updates */
2364 continue;
2365 }
2366 /* else _updates_left == 0 - infinite amount of updates */
2367
2368 /* send view */
2369 send_view (cli_ctx_iter, view_array, num_peers);
2370 }
2371}
struct ClientContext * cli_ctx_head
DLL with all clients currently connected to us.
static void send_view(const struct ClientContext *cli_ctx, const struct GNUNET_PeerIdentity *view_array, uint64_t view_size)
Send view to client.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
Struct used to store the context of a connected client.
struct ClientContext * next
DLL.
int64_t view_updates_left
How many updates this client expects to receive.

References cli_ctx_head, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, ClientContext::next, num_peers, send_view(), Sub::view, View_get_as_array(), View_size(), and ClientContext::view_updates_left.

Referenced by do_round(), and hist_update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clients_notify_stream_peer()

static void clients_notify_stream_peer ( const struct Sub sub,
uint64_t  num_peers,
const struct GNUNET_PeerIdentity peers 
)
static

sends updates to clients that are interested

Parameters
num_peersNumber of peers to send
peersthe array of peers to send

Definition at line 2381 of file gnunet-service-rps.c.

2385{
2386 struct ClientContext *cli_ctx_iter;
2387
2389 "Got peer (%s) from biased stream - update all clients\n",
2390 GNUNET_i2s (peers));
2391
2392 for (cli_ctx_iter = cli_ctx_head;
2393 NULL != cli_ctx_iter;
2394 cli_ctx_iter = cli_ctx_iter->next)
2395 {
2396 if ((GNUNET_YES == cli_ctx_iter->stream_update) &&
2397 ((sub == cli_ctx_iter->sub) || (sub == msub) ))
2398 {
2399 send_stream_peers (cli_ctx_iter, num_peers, peers);
2400 }
2401 }
2402}
static void send_stream_peers(const struct ClientContext *cli_ctx, uint64_t num_peers, const struct GNUNET_PeerIdentity *peers)
Send peer from biased stream to client.
int8_t stream_update
Whether this client wants to receive stream updates.

References cli_ctx_head, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_YES, LOG, msub, ClientContext::next, num_peers, peers, send_stream_peers(), ClientContext::stream_update, and ClientContext::sub.

Referenced by do_round(), hist_update(), and insert_in_view_op().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hist_update()

static void hist_update ( const struct GNUNET_PeerIdentity ids,
uint32_t  num_peers,
void *  cls 
)
static

Put random peer from sampler into the view as history update.

Parameters
idsArray of Peers to insert into view
num_peersNumber of peers to insert
clsClosure - The Sub for which this is to be done

Definition at line 2413 of file gnunet-service-rps.c.

2416{
2417 unsigned int i;
2418 struct Sub *sub = cls;
2419
2420 for (i = 0; i < num_peers; i++)
2421 {
2422 int inserted;
2423 if (GNUNET_YES != check_peer_known (sub->peer_map, &ids[i]))
2424 {
2426 "Peer in history update not known!\n");
2427 continue;
2428 }
2429 inserted = insert_in_view (sub, &ids[i]);
2430 if (GNUNET_OK == inserted)
2431 {
2432 clients_notify_stream_peer (sub, 1, &ids[i]);
2433 }
2434#ifdef TO_FILE_FULL
2435 to_file (sub->file_name_view_log,
2436 "+%s\t(history)",
2437 GNUNET_i2s_full (ids));
2438#endif /* TO_FILE_FULL */
2439 }
2441}

References check_peer_known(), clients_notify_stream_peer(), clients_notify_view_update(), GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s_full(), GNUNET_OK, GNUNET_YES, insert_in_view(), LOG, num_peers, Sub::peer_map, and to_file.

Referenced by do_round().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resize_wrapper()

static void resize_wrapper ( struct RPS_Sampler sampler,
uint32_t  new_size 
)
static

Wrapper around RPS_sampler_resize()

If we do not have enough sampler elements, double current sampler size If we have more than enough sampler elements, halv current sampler size

Parameters
samplerThe sampler to resize
new_sizeNew size to which to resize

Definition at line 2454 of file gnunet-service-rps.c.

2455{
2456 unsigned int sampler_size;
2457
2458 // TODO statistics
2459 // TODO respect the min, max
2460 sampler_size = RPS_sampler_get_size (sampler);
2461 if (sampler_size > new_size * 4)
2462 { /* Shrinking */
2463 RPS_sampler_resize (sampler, sampler_size / 2);
2464 }
2465 else if (sampler_size < new_size)
2466 { /* Growing */
2467 RPS_sampler_resize (sampler, sampler_size * 2);
2468 }
2469 LOG (GNUNET_ERROR_TYPE_DEBUG, "sampler_size is now %u\n", sampler_size);
2470}
void RPS_sampler_resize(struct RPS_Sampler *sampler, unsigned int new_size)
Grow or shrink the size of the sampler.
unsigned int RPS_sampler_get_size(struct RPS_Sampler *sampler)
Get the size of the sampler.

References GNUNET_ERROR_TYPE_DEBUG, LOG, RPS_sampler_get_size(), RPS_sampler_resize(), and Sub::sampler.

Referenced by adapt_sizes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_pull_reply()

static void send_pull_reply ( struct PeerContext peer_ctx,
const struct GNUNET_PeerIdentity peer_ids,
unsigned int  num_peer_ids 
)
static

Send a PULL REPLY to peer_id.

Parameters
peer_ctxContext of the peer to send the reply to
peer_idsthe peers to send to peer_id
num_peer_idsthe number of peers to send to peer_id

Definition at line 2523 of file gnunet-service-rps.c.

2526{
2527 uint32_t send_size;
2528 struct GNUNET_MQ_Envelope *ev;
2529 struct GNUNET_RPS_P2P_PullReplyMessage *out_msg;
2530
2531 /* Compute actual size */
2532 send_size = sizeof(struct GNUNET_RPS_P2P_PullReplyMessage)
2533 + num_peer_ids * sizeof(struct GNUNET_PeerIdentity);
2534
2536 /* Compute number of peers to send
2537 * If too long, simply truncate */
2538 // TODO select random ones via permutation
2539 // or even better: do good protocol design
2540 send_size =
2542 - sizeof(struct GNUNET_RPS_P2P_PullReplyMessage))
2543 / sizeof(struct GNUNET_PeerIdentity);
2544 else
2545 send_size = num_peer_ids;
2546
2548 "Going to send PULL REPLY with %u peers to %s\n",
2549 send_size, GNUNET_i2s (&peer_ctx->peer_id));
2550
2551 ev = GNUNET_MQ_msg_extra (out_msg,
2552 send_size * sizeof(struct GNUNET_PeerIdentity),
2554 out_msg->num_peers = htonl (send_size);
2555 GNUNET_memcpy (&out_msg[1], peer_ids,
2556 send_size * sizeof(struct GNUNET_PeerIdentity));
2557
2558 send_message (peer_ctx, ev, "PULL REPLY");
2559 if (peer_ctx->sub == msub)
2560 {
2561 GNUNET_STATISTICS_update (stats, "# pull reply send issued", 1, GNUNET_NO);
2562 }
2563 // TODO check with send intention: as send_channel is used/opened we indicate
2564 // a sending intention without intending it.
2565 // -> clean peer afterwards?
2566 // -> use recv_channel?
2567}
static void send_message(struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type)
Send a message to another peer.
#define GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE
Maximum message size that can be sent on CADET.
uint32_t num_peers
Number of PeerIDs sent.
Definition rps.h:53

References GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, GNUNET_MQ_msg_extra, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, msub, GNUNET_RPS_P2P_PullReplyMessage::num_peers, PeerContext::peer_id, send_message(), stats, and PeerContext::sub.

Referenced by handle_peer_pull_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_in_pull_map()

static void insert_in_pull_map ( void *  cls,
const struct GNUNET_PeerIdentity peer 
)
static

Insert PeerID in #pull_map.

Called once we know a peer is online.

Parameters
clsClosure - Sub with the pull map to insert into
peerPeer to insert

Definition at line 2579 of file gnunet-service-rps.c.

2581{
2582 struct Sub *sub = cls;
2583
2584 CustomPeerMap_put (sub->pull_map, peer);
2585}

References CustomPeerMap_put(), and Sub::pull_map.

Referenced by handle_peer_pull_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_in_sampler()

static void insert_in_sampler ( void *  cls,
const struct GNUNET_PeerIdentity peer 
)
static

Update sampler with given PeerID.

Implements PeerOp

Parameters
clsClosure - Sub containing the sampler to insert into
peerPeer to insert

Definition at line 2620 of file gnunet-service-rps.c.

2622{
2623 struct Sub *sub = cls;
2624
2626 "Updating samplers with peer %s from insert_in_sampler()\n",
2627 GNUNET_i2s (peer));
2628 RPS_sampler_update (sub->sampler, peer);
2629 if (0 < RPS_sampler_count_id (sub->sampler, peer))
2630 {
2631 /* Make sure we 'know' about this peer */
2632 (void) issue_peer_online_check (sub, peer);
2633 /* Establish a channel towards that peer to indicate we are going to send
2634 * messages to it */
2635 // indicate_sending_intention (peer);
2636 }
2637 if (sub == msub)
2638 {
2640 "# observed peers in gossip",
2641 1,
2642 GNUNET_NO);
2643 }
2644#ifdef TO_FILE
2645 sub->num_observed_peers++;
2648 peer,
2649 NULL,
2651 uint32_t num_observed_unique_peers =
2654 "# unique peers in gossip",
2655 num_observed_unique_peers,
2656 GNUNET_NO);
2657#ifdef TO_FILE_FULL
2658 to_file (sub->file_name_observed_log,
2659 "%" PRIu32 " %" PRIu32 " %f\n",
2660 sub->num_observed_peers,
2661 num_observed_unique_peers,
2662 1.0 * num_observed_unique_peers / sub->num_observed_peers)
2663#endif /* TO_FILE_FULL */
2664#endif /* TO_FILE */
2665}
void RPS_sampler_update(struct RPS_Sampler *sampler, const struct GNUNET_PeerIdentity *id)
Update every sampler element of this sampler with given peer.
uint32_t RPS_sampler_count_id(struct RPS_Sampler *sampler, const struct GNUNET_PeerIdentity *id)
Counts how many Samplers currently hold a given PeerID.
struct GNUNET_CONTAINER_MultiPeerMap * observed_unique_peers
Multipeermap (ab-) used to count unique peer_ids.
uint32_t num_observed_peers
Count the observed peers.

References GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), issue_peer_online_check(), LOG, msub, Sub::num_observed_peers, Sub::observed_unique_peers, RPS_sampler_count_id(), RPS_sampler_update(), Sub::sampler, stats, and to_file.

Referenced by do_round(), and got_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ got_peer()

static void got_peer ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

This is called on peers from external sources (cadet, peerinfo, ...) If the peer is not known, online check is issued and it is scheduled to be inserted in sampler and view.

"External sources" refer to every source except the gossip.

Parameters
subSub for which peer was received
peerpeer to insert/peer received

Definition at line 2679 of file gnunet-service-rps.c.

2681{
2682 /* If we did not know this peer already, insert it into sampler and view */
2683 if (GNUNET_YES == issue_peer_online_check (sub, peer))
2684 {
2686 &insert_in_sampler, sub);
2688 &insert_in_view_op, sub);
2689 }
2690 if (sub == msub)
2691 {
2693 "# learnd peers",
2694 1,
2695 GNUNET_NO);
2696 }
2697}

References get_peer_ctx(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, insert_in_sampler(), insert_in_view_op(), issue_peer_online_check(), msub, Sub::peer_map, schedule_operation(), and stats.

Referenced by handle_client_seed(), init_peer_cb(), process_peerinfo_peers(), and valid_peers_iterator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_sending_channel_needed()

static int check_sending_channel_needed ( const struct PeerContext peer_ctx)
static

Checks if there is a sending channel and if it is needed.

Parameters
peer_ctxContext of the peer to check
Returns
GNUNET_YES if sending channel exists and is still needed GNUNET_NO otherwise

Definition at line 2708 of file gnunet-service-rps.c.

2709{
2710 /* struct GNUNET_CADET_Channel *channel; */
2711 if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
2712 &peer_ctx->peer_id))
2713 {
2714 return GNUNET_NO;
2715 }
2716 if (GNUNET_YES == check_sending_channel_exists (peer_ctx))
2717 {
2718 if ((0 < RPS_sampler_count_id (peer_ctx->sub->sampler,
2719 &peer_ctx->peer_id)) ||
2720 (GNUNET_YES == View_contains_peer (peer_ctx->sub->view,
2721 &peer_ctx->peer_id)) ||
2723 &peer_ctx->peer_id)) ||
2725 &peer_ctx->peer_id)) ||
2726 (GNUNET_YES == check_peer_flag (peer_ctx->sub->peer_map,
2727 &peer_ctx->peer_id,
2729 { /* If we want to keep the connection to peer open */
2730 return GNUNET_YES;
2731 }
2732 return GNUNET_NO;
2733 }
2734 return GNUNET_NO;
2735}
static int check_sending_channel_exists(const struct PeerContext *peer_ctx)
Check whether a sending channel towards the given peer exists.
int CustomPeerMap_contains_peer(const struct CustomPeerMap *c_peer_map, const struct GNUNET_PeerIdentity *peer)
Check whether custom peer map contains a peer.
int View_contains_peer(const struct View *view, const struct GNUNET_PeerIdentity *peer)
Check whether view contains a peer.

References check_peer_flag(), check_peer_known(), check_sending_channel_exists(), CustomPeerMap_contains_peer(), GNUNET_NO, GNUNET_YES, PeerContext::peer_id, Sub::peer_map, Peers_PULL_REPLY_PENDING, Sub::pull_map, Sub::push_map, RPS_sampler_count_id(), Sub::sampler, PeerContext::sub, Sub::view, and View_contains_peer().

Referenced by clean_peer(), and cleanup_destroyed_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_peer()

static void remove_peer ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

remove peer from our knowledge, the view, push and pull maps and samplers.

Parameters
subSub with the data structures the peer is to be removed from
peerthe peer to remove

Definition at line 2746 of file gnunet-service-rps.c.

2748{
2749 (void) View_remove_peer (sub->view,
2750 peer);
2752 peer);
2754 peer);
2756 peer);
2757 /* We want to destroy the peer now.
2758 * Sometimes, it just seems that it's already been removed from the peer_map,
2759 * so check the peer_map first. */
2761 peer))
2762 {
2764 peer));
2765 }
2766}
int CustomPeerMap_remove_peer(const struct CustomPeerMap *c_peer_map, const struct GNUNET_PeerIdentity *peer)
Remove peer from custom peer map.
void RPS_sampler_reinitialise_by_value(struct RPS_Sampler *sampler, const struct GNUNET_PeerIdentity *id)
Reinitialise all previously initialised sampler elements with the given value.
int View_remove_peer(struct View *view, const struct GNUNET_PeerIdentity *peer)
Remove peer from view.

References check_peer_known(), CustomPeerMap_remove_peer(), destroy_peer(), get_peer_ctx(), GNUNET_YES, Sub::peer_map, Sub::pull_map, Sub::push_map, RPS_sampler_reinitialise_by_value(), Sub::sampler, Sub::view, and View_remove_peer().

Referenced by clean_peer(), and cleanup_destroyed_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clean_peer()

static void clean_peer ( struct Sub sub,
const struct GNUNET_PeerIdentity peer 
)
static

Remove data that is not needed anymore.

If the sending channel is no longer needed it is destroyed.

Parameters
subSub in which the current peer is to be cleaned
peerthe peer whose data is about to be cleaned

Definition at line 2778 of file gnunet-service-rps.c.

2780{
2782 peer)))
2783 {
2785 "Going to remove send channel to peer %s\n",
2786 GNUNET_i2s (peer));
2787 #if ENABLE_MALICIOUS
2788 if (0 != GNUNET_memcmp (&attacked_peer,
2789 peer))
2791 peer));
2792 #else /* ENABLE_MALICIOUS */
2794 peer));
2795 #endif /* ENABLE_MALICIOUS */
2796 }
2797
2799 peer))
2800 {
2801 /* Peer was already removed by callback on destroyed channel */
2803 "Peer was removed from our knowledge during cleanup\n");
2804 return;
2805 }
2806
2808 peer))) &&
2809 (GNUNET_NO == View_contains_peer (sub->view, peer)) &&
2812 (0 == RPS_sampler_count_id (sub->sampler, peer)) &&
2813 (GNUNET_YES == check_removable (get_peer_ctx (sub->peer_map, peer))))
2814 { /* We can safely remove this peer */
2816 "Going to remove peer %s\n",
2817 GNUNET_i2s (peer));
2818 remove_peer (sub, peer);
2819 return;
2820 }
2821}
static int check_removable(const struct PeerContext *peer_ctx)
Check if peer is removable.
static int destroy_sending_channel(struct PeerContext *peer_ctx)
Destroy the send channel of a peer e.g.

References check_peer_send_intention(), check_removable(), check_sending_channel_needed(), CustomPeerMap_contains_peer(), destroy_sending_channel(), get_peer_ctx(), GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_memcmp, GNUNET_NO, GNUNET_YES, LOG, Sub::peer_map, Sub::pull_map, Sub::push_map, remove_peer(), RPS_sampler_count_id(), Sub::sampler, Sub::view, and View_contains_peer().

Referenced by do_round(), and handle_peer_pull_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_sub()

struct Sub * new_sub ( const struct GNUNET_HashCode hash,
uint32_t  sampler_size,
struct GNUNET_TIME_Relative  round_interval 
)

Create a new Sub.

Parameters
hashHash of value shared among rps instances on other hosts that defines a subgroup to sample from.
sampler_sizeSize of the sampler
round_intervalInterval (in average) between two rounds
Returns
Sub

Definition at line 2882 of file gnunet-service-rps.c.

2885{
2886 struct Sub *sub;
2887
2888 sub = GNUNET_new (struct Sub);
2889
2890 /* With the hash generated from the secret value this service only connects
2891 * to rps instances that share the value */
2892 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
2893 GNUNET_MQ_hd_fixed_size (peer_check,
2895 struct GNUNET_MessageHeader,
2896 NULL),
2897 GNUNET_MQ_hd_fixed_size (peer_push,
2899 struct GNUNET_MessageHeader,
2900 NULL),
2901 GNUNET_MQ_hd_fixed_size (peer_pull_request,
2903 struct GNUNET_MessageHeader,
2904 NULL),
2905 GNUNET_MQ_hd_var_size (peer_pull_reply,
2908 NULL),
2910 };
2911 sub->hash = *hash;
2912 sub->cadet_port =
2914 &sub->hash,
2915 &handle_inbound_channel, /* Connect handler */
2916 sub, /* cls */
2917 NULL, /* WindowSize handler */
2918 &cleanup_destroyed_channel, /* Disconnect handler */
2919 cadet_handlers);
2920 if (NULL == sub->cadet_port)
2921 {
2923 "Cadet port `%s' is already in use.\n",
2925 GNUNET_assert (0);
2926 }
2927
2928 /* Set up general data structure to keep track about peers */
2930 if (GNUNET_OK !=
2932 "rps",
2933 "FILENAME_VALID_PEERS",
2934 &sub->filename_valid_peers))
2935 {
2937 "rps",
2938 "FILENAME_VALID_PEERS");
2939 }
2940 if (0 != strncmp ("DISABLE", sub->filename_valid_peers, 7))
2941 {
2942 char *tmp_filename_valid_peers;
2943 char str_hash[105];
2944
2945 GNUNET_snprintf (str_hash,
2946 sizeof(str_hash), "%s",
2947 GNUNET_h2s_full (hash));
2948 tmp_filename_valid_peers = sub->filename_valid_peers;
2950 "%s%s",
2951 tmp_filename_valid_peers,
2952 str_hash);
2953 GNUNET_free (tmp_filename_valid_peers);
2954 }
2956
2957 /* Set up the sampler */
2958 sub->sampler_size_est_min = sampler_size;
2959 sub->sampler_size_est_need = sampler_size;;
2960 LOG (GNUNET_ERROR_TYPE_DEBUG, "MINSIZE is %u\n", sub->sampler_size_est_min);
2961 GNUNET_assert (0 != round_interval.rel_value_us);
2962 sub->round_interval = round_interval;
2963 sub->sampler = RPS_sampler_init (sampler_size,
2964 round_interval);
2965
2966 /* Logging of internals */
2967#ifdef TO_FILE_FULL
2968 // FIXME: The service cannot know the index, which is required by this
2969 // function:
2970 // sub->file_name_view_log = store_prefix_file_name (&own_identity, "view");
2971#endif /* TO_FILE_FULL */
2972#ifdef TO_FILE
2973#ifdef TO_FILE_FULL
2974 // FIXME: The service cannot know the index, which is required by this
2975 // function:
2976 // sub->file_name_observed_log = store_prefix_file_name (&own_identity,
2977 // "observed");
2978#endif /* TO_FILE_FULL */
2979 sub->num_observed_peers = 0;
2981 GNUNET_NO);
2982#endif /* TO_FILE */
2983
2984 /* Set up data structures for gossip */
2985 sub->push_map = CustomPeerMap_create (4);
2986 sub->pull_map = CustomPeerMap_create (4);
2987 sub->view_size_est_min = sampler_size;;
2988 sub->view = View_create (sub->view_size_est_min);
2989 if (sub == msub)
2990 {
2992 "view size aim",
2993 sub->view_size_est_min,
2994 GNUNET_NO);
2995 }
2996
2997 /* Start executing rounds */
2999
3000 return sub;
3001}
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void * handle_inbound_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Handle the channel a peer opens to us.
struct CustomPeerMap * CustomPeerMap_create(unsigned int len)
Create an empty peermap.
struct RPS_Sampler * RPS_sampler_init(size_t init_size, struct GNUNET_TIME_Relative max_round_interval)
Initialise a tuple of sampler elements.
struct View * View_create(uint32_t len)
Create an empty view.
#define GNUNET_APPLICATION_PORT_RPS
Transfer of blocks for random peer sampling.
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition cadet_api.c:966
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
uint64_t rel_value_us
The actual value.
unsigned int sampler_size_est_need
The size of sampler we need to be able to satisfy the Brahms protocol's need of random peers.
unsigned int view_size_est_min
This is the minimum estimate used as view size.
unsigned int sampler_size_est_min
This is the minimum estimate used as sampler size.
struct GNUNET_CADET_Port * cadet_port
Port to communicate to other peers.

References cadet_handle, Sub::cadet_port, cfg, cleanup_destroyed_channel(), CustomPeerMap_create(), do_round(), Sub::do_round_task, Sub::filename_valid_peers, GNUNET_APPLICATION_PORT_RPS, GNUNET_asprintf(), GNUNET_assert, GNUNET_CADET_open_port(), GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s_full(), GNUNET_log_config_missing(), GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_snprintf(), GNUNET_STATISTICS_set(), handle_inbound_channel(), Sub::hash, LOG, msub, Sub::num_observed_peers, Sub::observed_unique_peers, Sub::peer_map, Sub::pull_map, Sub::push_map, GNUNET_TIME_Relative::rel_value_us, Sub::round_interval, RPS_sampler_init(), Sub::sampler, Sub::sampler_size_est_min, Sub::sampler_size_est_need, stats, Sub::valid_peers, Sub::view, View_create(), and Sub::view_size_est_min.

Referenced by handle_client_start_sub(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_sub()

static void destroy_sub ( struct Sub sub)
static

Destroy Sub.

Parameters
subSub to destroy

Definition at line 3060 of file gnunet-service-rps.c.

3061{
3062 GNUNET_assert (NULL != sub);
3063 GNUNET_assert (NULL != sub->do_round_task);
3065 sub->do_round_task = NULL;
3066
3067 /* Disconnect from cadet */
3069 sub->cadet_port = NULL;
3070
3071 /* Clean up data structures for peers */
3073 sub->sampler = NULL;
3074 View_destroy (sub->view);
3075 sub->view = NULL;
3077 sub->push_map = NULL;
3079 sub->pull_map = NULL;
3080 peers_terminate (sub);
3081
3082 /* Free leftover data structures */
3083#ifdef TO_FILE_FULL
3084 GNUNET_free (sub->file_name_view_log);
3085 sub->file_name_view_log = NULL;
3086#endif /* TO_FILE_FULL */
3087#ifdef TO_FILE
3088#ifdef TO_FILE_FULL
3089 GNUNET_free (sub->file_name_observed_log);
3090 sub->file_name_observed_log = NULL;
3091#endif /* TO_FILE_FULL */
3092
3093 // FIXME: Currently this calls malfunctionning code
3094 // /* Write push frequencies to disk */
3095 // write_histogram_to_file (sub->push_recv,
3096 // "push_recv");
3097
3098 // /* Write push deltas to disk */
3099 // write_histogram_to_file (sub->push_delta,
3100 // "push_delta");
3101
3102 // /* Write pull delays to disk */
3103 // write_histogram_to_file (sub->pull_delays,
3104 // "pull_delays");
3105
3107 sub->observed_unique_peers = NULL;
3108#endif /* TO_FILE */
3109
3110 GNUNET_free (sub);
3111}
static void peers_terminate(struct Sub *sub)
Delete storage of peers that was created with #initialise_peers ()
void CustomPeerMap_destroy(struct CustomPeerMap *c_peer_map)
Destroy peermap.
void RPS_sampler_destroy(struct RPS_Sampler *sampler)
Cleans the samplers.
void View_destroy(struct View *view)
Destroy view.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition cadet_api.c:804

References Sub::cadet_port, CustomPeerMap_destroy(), Sub::do_round_task, GNUNET_assert, GNUNET_CADET_close_port(), GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_free, GNUNET_SCHEDULER_cancel(), Sub::observed_unique_peers, peers_terminate(), Sub::pull_map, Sub::push_map, RPS_sampler_destroy(), Sub::sampler, Sub::view, and View_destroy().

Referenced by destroy_cli_ctx(), handle_client_start_sub(), handle_client_stop_sub(), and shutdown_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ core_init()

void core_init ( void *  cls,
const struct GNUNET_PeerIdentity my_identity 
)

Callback on initialisation of Core.

Parameters
cls- unused
my_identity- unused

Definition at line 3130 of file gnunet-service-rps.c.

3132{
3133 (void) cls;
3134 (void) my_identity;
3135
3137}
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.

References GNUNET_MQ_MessageHandler::cls, GNUNET_CONTAINER_multipeermap_create(), GNUNET_NO, map_single_hop, and my_identity.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ core_connects()

void * core_connects ( void *  cls,
const struct GNUNET_PeerIdentity peer,
struct GNUNET_MQ_Handle mq,
enum GNUNET_CORE_PeerClass  class 
)

Callback for core.

Method called whenever a given peer connects.

Parameters
clsclosure - unused
peerpeer identity this notification is about
classclass of the connecting peer
Returns
closure given to core_disconnects as peer_cls

Definition at line 3150 of file gnunet-service-rps.c.

3154{
3155 (void) cls;
3156 (void) mq;
3157
3160 peer,
3161 NULL,
3163 return NULL;
3164}

References GNUNET_MQ_MessageHandler::cls, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_YES, map_single_hop, and mq.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ core_disconnects()

void core_disconnects ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  peer_cls 
)

Callback for core.

Method called whenever a peer disconnects.

Parameters
clsclosure - unused
peerpeer identity this notification is about
peer_clsclosure given in core_connects - unused

Definition at line 3176 of file gnunet-service-rps.c.

3179{
3180 (void) cls;
3181 (void) peer_cls;
3182
3184}

References GNUNET_MQ_MessageHandler::cls, GNUNET_CONTAINER_multipeermap_remove_all(), and map_single_hop.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_cli_ctx()

static void destroy_cli_ctx ( struct ClientContext cli_ctx)
static

Destroy the context for a (connected) client.

Parameters
cli_ctxContext to destroy

Definition at line 3198 of file gnunet-service-rps.c.

3199{
3200 GNUNET_assert (NULL != cli_ctx);
3203 cli_ctx);
3204 if (NULL != cli_ctx->sub)
3205 {
3206 destroy_sub (cli_ctx->sub);
3207 cli_ctx->sub = NULL;
3208 }
3209 GNUNET_free (cli_ctx);
3210}
struct ClientContext * cli_ctx_tail
static void destroy_sub(struct Sub *sub)
Destroy Sub.

References cli_ctx_head, cli_ctx_tail, destroy_sub(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, and ClientContext::sub.

Referenced by client_disconnect_cb(), handle_client_view_cancel(), and shutdown_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ adapt_sizes()

static void adapt_sizes ( struct Sub sub,
double  logestimate,
double  std_dev 
)
static

Update sizes in sampler and view on estimate update from nse service.

Parameters
subSub
logestimatethe log(Base 2) value of the current network size estimate
std_devstandard deviation for the estimate

Definition at line 3221 of file gnunet-service-rps.c.

3222{
3223 double estimate;
3224
3225 // double scale; // TODO this might go global/config
3226
3228 "Received a ns estimate - logest: %f, std_dev: %f (old_size: %u)\n",
3229 logestimate, std_dev, RPS_sampler_get_size (sub->sampler));
3230 // scale = .01;
3231 estimate = GNUNET_NSE_log_estimate_to_n (logestimate);
3232 // GNUNET_NSE_log_estimate_to_n (logestimate);
3233 estimate = pow (estimate, 1.0 / 3);
3234 // TODO add if std_dev is a number
3235 // estimate += (std_dev * scale);
3236 if (sub->view_size_est_min < ceil (estimate))
3237 {
3238 LOG (GNUNET_ERROR_TYPE_DEBUG, "Changing estimate to %f\n", estimate);
3239 sub->sampler_size_est_need = estimate;
3240 sub->view_size_est_need = estimate;
3241 }
3242 else
3243 {
3244 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not using estimate %f\n", estimate);
3245 // sub->sampler_size_est_need = sub->view_size_est_min;
3247 }
3248 if (sub == msub)
3249 {
3251 "view size aim",
3252 sub->view_size_est_need,
3253 GNUNET_NO);
3254 }
3255
3256 /* If the NSE has changed adapt the lists accordingly */
3259}
static void resize_wrapper(struct RPS_Sampler *sampler, uint32_t new_size)
Wrapper around RPS_sampler_resize()
void View_change_len(struct View *view, uint32_t len)
Change length of view.
#define GNUNET_NSE_log_estimate_to_n(loge)
Convert the logarithmic estimated returned to the 'GNUNET_NSE_Callback' into an absolute estimate in ...

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_NSE_log_estimate_to_n, GNUNET_STATISTICS_set(), LOG, msub, resize_wrapper(), RPS_sampler_get_size(), Sub::sampler, Sub::sampler_size_est_need, stats, Sub::view, View_change_len(), Sub::view_size_est_min, and Sub::view_size_est_need.

Referenced by nse_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nse_callback()

static void nse_callback ( void *  cls,
struct GNUNET_TIME_Absolute  timestamp,
double  logestimate,
double  std_dev 
)
static

Function called by NSE.

Updates sizes of sampler list and view and adapt those lists accordingly.

implements GNUNET_NSE_Callback

Parameters
clsClosure - unused
timestamptime when the estimate was received from the server (or created by the server)
logestimatethe log(Base 2) value of the current network size estimate
std_devstandard deviation for the estimate

Definition at line 3276 of file gnunet-service-rps.c.

3279{
3280 (void) cls;
3281 (void) timestamp;
3282 struct ClientContext *cli_ctx_iter;
3283
3284 adapt_sizes (msub, logestimate, std_dev);
3285 for (cli_ctx_iter = cli_ctx_head;
3286 NULL != cli_ctx_iter;
3287 cli_ctx_iter = cli_ctx_iter->next)
3288 {
3289 if (NULL != cli_ctx_iter->sub)
3290 {
3291 adapt_sizes (cli_ctx_iter->sub, logestimate, std_dev);
3292 }
3293 }
3294}
static uint64_t timestamp(void)
Get current timestamp.
static void adapt_sizes(struct Sub *sub, double logestimate, double std_dev)
Update sizes in sampler and view on estimate update from nse service.

References adapt_sizes(), cli_ctx_head, GNUNET_MQ_MessageHandler::cls, msub, ClientContext::next, ClientContext::sub, and timestamp().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_client_seed()

static int check_client_seed ( void *  cls,
const struct GNUNET_RPS_CS_SeedMessage msg 
)
static

This function is called, when the client seeds peers.

It verifies that msg is well-formed.

Parameters
clsthe closure (ClientContext)
msgthe message
Returns
GNUNET_OK if msg is well-formed GNUNET_SYSERR otherwise

Definition at line 3307 of file gnunet-service-rps.c.

3308{
3309 struct ClientContext *cli_ctx = cls;
3310 uint16_t msize = ntohs (msg->header.size);
3311 uint32_t num_peers = ntohl (msg->num_peers);
3312
3313 msize -= sizeof(struct GNUNET_RPS_CS_SeedMessage);
3314 if ((msize / sizeof(struct GNUNET_PeerIdentity) != num_peers) ||
3315 (msize % sizeof(struct GNUNET_PeerIdentity) != 0))
3316 {
3318 "message says it sends %" PRIu32 " peers, have space for %lu peers\n",
3319 ntohl (msg->num_peers),
3320 (msize / sizeof(struct GNUNET_PeerIdentity)));
3321 GNUNET_break (0);
3323 return GNUNET_SYSERR;
3324 }
3325 return GNUNET_OK;
3326}
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2463
struct GNUNET_SERVICE_Client * client
The client handle to send the reply to.
Message from client to service with seed of peers.
Definition rps.h:67

References ClientContext::client, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_OK, GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, LOG, msg, num_peers, and GNUNET_MessageHeader::size.

Here is the call graph for this function:

◆ handle_client_seed()

static void handle_client_seed ( void *  cls,
const struct GNUNET_RPS_CS_SeedMessage msg 
)
static

Handle seed from the client.

Parameters
clsclosure
msgthe actual message

Definition at line 3336 of file gnunet-service-rps.c.

3338{
3339 struct ClientContext *cli_ctx = cls;
3340 struct GNUNET_PeerIdentity *peers;
3341 uint32_t num_peers;
3342 uint32_t i;
3343
3344 num_peers = ntohl (msg->num_peers);
3345 peers = (struct GNUNET_PeerIdentity *) &msg[1];
3346
3348 "Client seeded peers:\n");
3350
3351 for (i = 0; i < num_peers; i++)
3352 {
3354 "Updating samplers with seed %" PRIu32 ": %s\n",
3355 i,
3356 GNUNET_i2s (&peers[i]));
3357
3358 if (NULL != msub)
3359 got_peer (msub, &peers[i]); /* Condition needed? */
3360 if (NULL != cli_ctx->sub)
3361 got_peer (cli_ctx->sub, &peers[i]);
3362 }
3364}
static void got_peer(struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
This is called on peers from external sources (cadet, peerinfo, ...) If the peer is not known,...
static void print_peer_list(struct GNUNET_PeerIdentity *list, unsigned int len)
Print peerlist to log.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434

References ClientContext::client, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_SERVICE_client_continue(), got_peer(), LOG, msg, msub, num_peers, peers, print_peer_list(), and ClientContext::sub.

Here is the call graph for this function:

◆ handle_client_view_request()

static void handle_client_view_request ( void *  cls,
const struct GNUNET_RPS_CS_DEBUG_ViewRequest msg 
)
static

Handle RPS request from the client.

Parameters
clsClient context
msgMessage containing the number of updates the client wants to receive

Definition at line 3375 of file gnunet-service-rps.c.

3377{
3378 struct ClientContext *cli_ctx = cls;
3379 uint64_t num_updates;
3380
3381 num_updates = ntohl (msg->num_updates);
3382
3384 "Client requested %" PRIu64 " updates of view.\n",
3385 num_updates);
3386
3387 GNUNET_assert (NULL != cli_ctx);
3388 cli_ctx->view_updates_left = num_updates;
3389 send_view (cli_ctx, NULL, 0);
3391}

References ClientContext::client, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SERVICE_client_continue(), LOG, msg, send_view(), and ClientContext::view_updates_left.

Here is the call graph for this function:

◆ handle_client_view_cancel()

static void handle_client_view_cancel ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handle the cancellation of the view updates.

Parameters
clsThe client context
msgUnused

Definition at line 3401 of file gnunet-service-rps.c.

3403{
3404 struct ClientContext *cli_ctx = cls;
3405
3406 (void) msg;
3407
3409 "Client does not want to receive updates of view any more.\n");
3410
3411 GNUNET_assert (NULL != cli_ctx);
3412 cli_ctx->view_updates_left = 0;
3414 if (GNUNET_YES == cli_ctx->stream_update)
3415 {
3416 destroy_cli_ctx (cli_ctx);
3417 }
3418}
static void destroy_cli_ctx(struct ClientContext *cli_ctx)
Destroy the context for a (connected) client.

References ClientContext::client, destroy_cli_ctx(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SERVICE_client_continue(), GNUNET_YES, LOG, msg, ClientContext::stream_update, and ClientContext::view_updates_left.

Here is the call graph for this function:

◆ handle_client_stream_request()

static void handle_client_stream_request ( void *  cls,
const struct GNUNET_RPS_CS_DEBUG_StreamRequest msg 
)
static

Handle RPS request for biased stream from the client.

Parameters
clsClient context
msgunused

Definition at line 3428 of file gnunet-service-rps.c.

3431{
3432 struct ClientContext *cli_ctx = cls;
3433
3434 (void) msg;
3435
3437 "Client requested peers from biased stream.\n");
3438 cli_ctx->stream_update = GNUNET_YES;
3439
3440 GNUNET_assert (NULL != cli_ctx);
3442}

References ClientContext::client, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SERVICE_client_continue(), GNUNET_YES, LOG, msg, and ClientContext::stream_update.

Here is the call graph for this function:

◆ handle_client_stream_cancel()

static void handle_client_stream_cancel ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handles the cancellation of the stream of biased peer ids.

Parameters
clsThe client context
msgunused

Definition at line 3452 of file gnunet-service-rps.c.

3454{
3455 struct ClientContext *cli_ctx = cls;
3456
3457 (void) msg;
3458
3460 "Client canceled receiving peers from biased stream.\n");
3461 cli_ctx->stream_update = GNUNET_NO;
3462
3463 GNUNET_assert (NULL != cli_ctx);
3465}

References ClientContext::client, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SERVICE_client_continue(), LOG, msg, and ClientContext::stream_update.

Here is the call graph for this function:

◆ handle_client_start_sub()

static void handle_client_start_sub ( void *  cls,
const struct GNUNET_RPS_CS_SubStartMessage msg 
)
static

Create and start a Sub.

Parameters
clsClosure - unused
msgMessage containing the necessary information

Definition at line 3475 of file gnunet-service-rps.c.

3477{
3478 struct ClientContext *cli_ctx = cls;
3479
3480 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client requested start of a new sub.\n");
3481 if ((NULL != cli_ctx->sub) &&
3482 (0 != memcmp (&cli_ctx->sub->hash,
3483 &msg->hash,
3484 sizeof(struct GNUNET_HashCode))) )
3485 {
3487 "Already have a Sub with different share for this client. Remove old one, add new.\n");
3488 destroy_sub (cli_ctx->sub);
3489 cli_ctx->sub = NULL;
3490 }
3491 cli_ctx->sub = new_sub (&msg->hash,
3492 msub->sampler_size_est_min, // TODO make api input?
3493 GNUNET_TIME_relative_ntoh (msg->round_interval));
3495}
struct Sub * new_sub(const struct GNUNET_HashCode *hash, uint32_t sampler_size, struct GNUNET_TIME_Relative round_interval)
Create a new Sub.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition time.c:626
A 512-bit hashcode.

References ClientContext::client, destroy_sub(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_SERVICE_client_continue(), GNUNET_TIME_relative_ntoh(), Sub::hash, LOG, msg, msub, new_sub(), Sub::sampler_size_est_min, and ClientContext::sub.

Here is the call graph for this function:

◆ handle_client_stop_sub()

static void handle_client_stop_sub ( void *  cls,
const struct GNUNET_RPS_CS_SubStopMessage msg 
)
static

Destroy the Sub.

Parameters
clsClosure - unused
msgMessage containing the hash that identifies the Sub

Definition at line 3505 of file gnunet-service-rps.c.

3507{
3508 struct ClientContext *cli_ctx = cls;
3509
3510 GNUNET_assert (NULL != cli_ctx->sub);
3511 if (0 != memcmp (&cli_ctx->sub->hash, &msg->hash, sizeof(struct
3513 {
3515 "Share of current sub and request differ!\n");
3516 }
3517 destroy_sub (cli_ctx->sub);
3518 cli_ctx->sub = NULL;
3520}

References ClientContext::client, destroy_sub(), GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_SERVICE_client_continue(), Sub::hash, LOG, msg, and ClientContext::sub.

Here is the call graph for this function:

◆ compute_rand_delay()

static struct GNUNET_TIME_Relative compute_rand_delay ( struct GNUNET_TIME_Relative  mean,
unsigned int  spread 
)
static

Compute a random delay.

A uniformly distributed value between mean + spread and mean - spread.

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.

Parameters
meanthe mean time until the next round
spreadthe inverse amount of deviation from the mean

Compute random value between (0 and 1) * round_interval via multiplying round_interval with a 'fraction' (0 to value)/value

Definition at line 3876 of file gnunet-service-rps.c.

3878{
3879 struct GNUNET_TIME_Relative half_interval;
3881 unsigned int rand_delay;
3882 unsigned int max_rand_delay;
3883
3884 if (0 == spread)
3885 {
3887 "Not accepting spread of 0\n");
3888 GNUNET_break (0);
3889 GNUNET_assert (0);
3890 }
3891 GNUNET_assert (0 != mean.rel_value_us);
3892
3893 /* Compute random time value between spread * mean and spread * mean */
3894 half_interval = GNUNET_TIME_relative_divide (mean, spread);
3895
3896 max_rand_delay = GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us
3897 / mean.rel_value_us * (2 / spread);
3903 max_rand_delay);
3904 ret = GNUNET_TIME_relative_saturating_multiply (mean, rand_delay);
3905 ret = GNUNET_TIME_relative_divide (ret, max_rand_delay);
3906 ret = GNUNET_TIME_relative_add (ret, half_interval);
3907
3908 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == ret.rel_value_us)
3910 "Returning FOREVER_REL\n");
3911
3912 return ret;
3913}
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition time.c:529
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition time.c:583
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition time.c:548

References GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_WARNING, GNUNET_TIME_relative_add(), GNUNET_TIME_relative_divide(), GNUNET_TIME_relative_saturating_multiply(), GNUNET_TIME_UNIT_FOREVER_REL, LOG, and ret.

Referenced by do_round().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_pull_request()

static void send_pull_request ( struct PeerContext peer_ctx)
static

Send single pull request.

Parameters
peer_ctxContext to the peer to send request to

Definition at line 3922 of file gnunet-service-rps.c.

3923{
3924 struct GNUNET_MQ_Envelope *ev;
3925
3927 &peer_ctx->peer_id,
3929 SET_PEER_FLAG (peer_ctx,
3931 peer_ctx->round_pull_req = peer_ctx->sub->num_rounds;
3932
3934 "Going to send PULL REQUEST to peer %s.\n",
3935 GNUNET_i2s (&peer_ctx->peer_id));
3936
3938 send_message (peer_ctx,
3939 ev,
3940 "PULL REQUEST");
3941 if (peer_ctx->sub)
3942 {
3944 "# pull request send issued",
3945 1,
3946 GNUNET_NO);
3947 if ((NULL != map_single_hop) &&
3949 &peer_ctx->peer_id
3950 )))
3951 {
3953 "# pull request send issued (multi-hop peer)",
3954 1,
3955 GNUNET_NO);
3956 }
3957 }
3958}

References check_peer_flag(), GNUNET_assert, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, GNUNET_MQ_msg_header, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, map_single_hop, Sub::num_rounds, PeerContext::peer_id, Sub::peer_map, Peers_PULL_REPLY_PENDING, PeerContext::round_pull_req, send_message(), SET_PEER_FLAG, stats, and PeerContext::sub.

Referenced by do_round().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_push()

static void send_push ( struct PeerContext peer_ctx)
static

Send single push.

Parameters
peer_ctxContext of peer to send push to

Definition at line 3967 of file gnunet-service-rps.c.

3968{
3969 struct GNUNET_MQ_Envelope *ev;
3970
3972 "Going to send PUSH to peer %s.\n",
3973 GNUNET_i2s (&peer_ctx->peer_id));
3974
3976 send_message (peer_ctx, ev, "PUSH");
3977 if (peer_ctx->sub)
3978 {
3980 "# push send issued",
3981 1,
3982 GNUNET_NO);
3983 if ((NULL != map_single_hop) &&
3985 &peer_ctx->peer_id
3986 )))
3987 {
3989 "# push send issued (multi-hop peer)",
3990 1,
3991 GNUNET_NO);
3992 }
3993 }
3994}

References GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, GNUNET_MQ_msg_header, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, map_single_hop, PeerContext::peer_id, send_message(), stats, and PeerContext::sub.

Referenced by do_round().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_peer_cb()

void init_peer_cb ( void *  cls,
const struct GNUNET_PeerIdentity peer,
int  tunnel,
unsigned int  n_paths,
unsigned int  best_path 
)

This is called from GNUNET_CADET_get_peers().

It is called on every peer(ID) that cadet somehow has contact with. We use those to initialise the sampler.

implements GNUNET_CADET_PeersCB

Parameters
clsClosure - Sub
peerPeer, or NULL on "EOF".
tunnelDo we have a tunnel towards this peer?
n_pathsNumber of known paths towards this peer.
best_pathHow long is the best path? (0 = unknown, 1 = ourselves, 2 = neighbor)

Definition at line 4647 of file gnunet-service-rps.c.

4653{
4654 struct Sub *sub = cls;
4655
4656 (void) tunnel;
4657 (void) n_paths;
4658 (void) best_path;
4659
4660 if (NULL != peer)
4661 {
4663 "Got peer_id %s from cadet\n",
4664 GNUNET_i2s (peer));
4665 got_peer (sub, peer);
4666 }
4667}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), got_peer(), and LOG.

Here is the call graph for this function:

◆ valid_peers_iterator()

static int valid_peers_iterator ( void *  cls,
const struct GNUNET_PeerIdentity peer 
)
static

Iterator function over stored, valid peers.

We initialise the sampler with those.

Parameters
clsClosure - Sub
peerthe peer id
Returns
GNUNET_YES if we should continue to iterate, GNUNET_NO if not.

Definition at line 4682 of file gnunet-service-rps.c.

4684{
4685 struct Sub *sub = cls;
4686
4687 if (NULL != peer)
4688 {
4690 "Got stored, valid peer %s\n",
4691 GNUNET_i2s (peer));
4692 got_peer (sub, peer);
4693 }
4694 return GNUNET_YES;
4695}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_YES, got_peer(), and LOG.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_peerinfo_peers()

void process_peerinfo_peers ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)

Iterator over peers from peerinfo.

Parameters
clsClosure - Sub
peerid of the peer, NULL for last call
hellohello message for the peer (can be NULL)
err_msgerror message

Definition at line 4707 of file gnunet-service-rps.c.

4710{
4711 struct Sub *sub = cls;
4712 (void) emsg;
4713
4715 "Got peer_id %s from peerinfo\n",
4716 GNUNET_i2s (&record->peer));
4717 got_peer (sub, &record->peer);
4719}
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static struct GNUNET_PEERSTORE_Monitor * peerstore_notify
Our peerstore notification context.
void GNUNET_PEERSTORE_monitor_next(struct GNUNET_PEERSTORE_Monitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_PEERSTORE_monitor_start for the next record(s).

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_PEERSTORE_monitor_next(), got_peer(), LOG, peerstore_notify, and record().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Task run during shutdown.

Parameters
clsClosure - unused

Definition at line 4728 of file gnunet-service-rps.c.

4729{
4730 struct ClientContext *client_ctx;
4731
4732 (void) cls;
4734 "RPS service is going down\n");
4735
4736 /* Clean all clients */
4737 for (client_ctx = cli_ctx_head;
4738 NULL != cli_ctx_head;
4739 client_ctx = cli_ctx_head)
4740 {
4741 destroy_cli_ctx (client_ctx);
4742 }
4743 if (NULL != msub)
4744 {
4745 destroy_sub (msub);
4746 msub = NULL;
4747 }
4748
4749 /* Disconnect from other services */
4751 peerstore_notify = NULL;
4753 peerstore = NULL;
4755 nse = NULL;
4756 if (NULL != core_handle)
4757 {
4758 /* core_init was called - core was initialised */
4759 /* disconnect first, so no callback tries to access missing peermap */
4761 core_handle = NULL;
4762 }
4763 if (NULL != map_single_hop)
4764 {
4766 map_single_hop = NULL;
4767 }
4768
4769 if (NULL != stats)
4770 {
4772 GNUNET_NO);
4773 stats = NULL;
4774 }
4776 cadet_handle = NULL;
4777#if ENABLE_MALICIOUS
4778 {
4779 struct AttackedPeer *tmp_att_peer;
4780
4781 GNUNET_array_grow (mal_peers,
4782 num_mal_peers,
4783 0);
4784 if (NULL != mal_peer_set)
4786 if (NULL != att_peer_set)
4788 while (NULL != att_peers_head)
4789 {
4790 tmp_att_peer = att_peers_head;
4791 GNUNET_CONTAINER_DLL_remove (att_peers_head,
4792 att_peers_tail,
4793 tmp_att_peer);
4794 GNUNET_free (tmp_att_peer);
4795 }
4796 }
4797#endif /* ENABLE_MALICIOUS */
4798 close_all_files ();
4799}
static struct GNUNET_NSE_Handle * nse
Handler to NSE.
static struct GNUNET_PEERSTORE_Handle * peerstore
Handle to the PEERSTORE service.
struct GNUNET_CORE_Handle * core_handle
Handle to CORE.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition cadet_api.c:777
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition core_api.c:744
void GNUNET_NSE_disconnect(struct GNUNET_NSE_Handle *h)
Disconnect from network size estimation service.
Definition nse_api.c:192
void GNUNET_PEERSTORE_monitor_stop(struct GNUNET_PEERSTORE_Monitor *zm)
Stop monitoring.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
int close_all_files()
Close all files that were opened with get_file_handle.

References cadet_handle, cli_ctx_head, close_all_files(), core_handle, destroy_cli_ctx(), destroy_sub(), GNUNET_array_grow, GNUNET_CADET_disconnect(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CORE_disconnect(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NO, GNUNET_NSE_disconnect(), GNUNET_PEERSTORE_disconnect(), GNUNET_PEERSTORE_monitor_stop(), GNUNET_STATISTICS_destroy(), LOG, map_single_hop, msub, nse, peerstore, peerstore_notify, and stats.

Here is the call graph for this function:

◆ client_connect_cb()

static void * client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
struct GNUNET_MQ_Handle mq 
)
static

Handle client connecting to the service.

Parameters
clsunused
clientthe new client
mqthe message queue of client
Returns
client

Definition at line 4811 of file gnunet-service-rps.c.

4814{
4815 struct ClientContext *cli_ctx;
4816
4817 (void) cls;
4818
4820 "Client connected\n");
4821 if (NULL == client)
4822 return client; /* Server was destroyed before a client connected. Shutting down */
4823 cli_ctx = GNUNET_new (struct ClientContext);
4824 cli_ctx->mq = mq;
4825 cli_ctx->view_updates_left = -1;
4826 cli_ctx->stream_update = GNUNET_NO;
4827 cli_ctx->client = client;
4830 cli_ctx);
4831 return cli_ctx;
4832}

References cli_ctx_head, cli_ctx_tail, ClientContext::client, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_NO, LOG, ClientContext::mq, mq, ClientContext::stream_update, and ClientContext::view_updates_left.

◆ client_disconnect_cb()

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

Callback called when a client disconnected from the service.

Parameters
clsclosure for the service
clientthe client that disconnected
internal_clsshould be equal to c

Definition at line 4843 of file gnunet-service-rps.c.

4846{
4847 struct ClientContext *cli_ctx = internal_cls;
4848
4849 (void) cls;
4850 GNUNET_assert (client == cli_ctx->client);
4851 if (NULL == client)
4852 { /* shutdown task - destroy all clients */
4853 while (NULL != cli_ctx_head)
4855 }
4856 else
4857 { /* destroy this client */
4859 "Client disconnected. Destroy its context.\n");
4860 destroy_cli_ctx (cli_ctx);
4861 }
4862}

References cli_ctx_head, ClientContext::client, destroy_cli_ctx(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, and LOG.

Here is the call graph for this function:

◆ error_cb()

static void error_cb ( void *  cls)
static

Definition at line 4866 of file gnunet-service-rps.c.

4867{
4869 "Error in PEERSTORE monitoring\n");
4870}

References GNUNET_ERROR_TYPE_WARNING, and GNUNET_log.

Referenced by run().

Here is the caller graph for this function:

◆ sync_cb()

static void sync_cb ( void *  cls)
static

Definition at line 4874 of file gnunet-service-rps.c.

4875{
4877 "Done with initial PEERSTORE iteration during monitoring\n");
4878}

References GNUNET_ERROR_TYPE_WARNING, and GNUNET_log.

Referenced by run().

Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle c,
struct GNUNET_SERVICE_Handle service 
)
static

Handle random peer sampling clients.

Parameters
clsclosure
cconfiguration to use
servicethe initialized service

Definition at line 4889 of file gnunet-service-rps.c.

4892{
4893 struct GNUNET_TIME_Relative round_interval;
4894 long long unsigned int sampler_size;
4895 char hash_port_string[] = GNUNET_APPLICATION_PORT_RPS;
4896 struct GNUNET_HashCode hash;
4897 const struct GNUNET_CORE_ServiceInfo service_info = {
4899 .version = { 1, 0 },
4900 .version_max = { 1, 0 },
4901 .version_min = { 1, 0 },
4902 };
4903
4904 (void) cls;
4905 (void) service;
4906
4907 GNUNET_log_setup ("rps",
4909 NULL);
4910 cfg = c;
4911 /* Get own ID */
4913 &own_identity); // TODO check return value
4915 "STARTING SERVICE (rps) for peer [%s]\n",
4917#if ENABLE_MALICIOUS
4919 "Malicious execution compiled in.\n");
4920#endif /* ENABLE_MALICIOUS */
4921
4922 /* Get time interval from the configuration */
4923 if (GNUNET_OK !=
4925 "RPS",
4926 "ROUNDINTERVAL",
4927 &round_interval))
4928 {
4930 "RPS", "ROUNDINTERVAL");
4932 return;
4933 }
4934
4935 /* Get initial size of sampler/view from the configuration */
4936 if (GNUNET_OK !=
4938 "RPS",
4939 "MINSIZE",
4940 &sampler_size))
4941 {
4943 "RPS", "MINSIZE");
4945 return;
4946 }
4947
4949 GNUNET_assert (NULL != cadet_handle);
4951 NULL, /* cls */
4952 core_init, /* init */
4953 core_connects, /* connects */
4954 core_disconnects, /* disconnects */
4955 NULL,
4956 &service_info); /* handlers */
4957 GNUNET_assert (NULL != core_handle);
4958
4959
4960 alpha = 0.45;
4961 beta = 0.45;
4962
4963
4964 /* Set up main Sub */
4965 GNUNET_CRYPTO_hash (hash_port_string,
4966 strlen (hash_port_string),
4967 &hash);
4968 msub = new_sub (&hash,
4969 sampler_size, /* Will be overwritten by config */
4970 round_interval);
4971
4972
4974
4975 /* connect to NSE */
4977
4978 // LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting peers from CADET\n");
4979 // GNUNET_CADET_get_peers (cadet_handle, &init_peer_cb, msub);
4980 // TODO send push/pull to each of those peers?
4981 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting stored valid peers\n");
4984
4987 GNUNET_YES,
4988 "peerstore",
4989 NULL,
4991 &error_cb,
4992 NULL,
4993 &sync_cb,
4994 NULL,
4996 msub);
4997
4998 LOG (GNUNET_ERROR_TYPE_INFO, "Ready to receive requests from clients\n");
4999
5002}
struct GNUNET_SCHEDULER_Task * shutdown_task
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static void sync_cb(void *cls)
void core_init(void *cls, const struct GNUNET_PeerIdentity *my_identity)
Callback on initialisation of Core.
static struct GNUNET_PeerIdentity own_identity
Our own identity.
void process_peerinfo_peers(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Iterator over peers from peerinfo.
static void nse_callback(void *cls, struct GNUNET_TIME_Absolute timestamp, double logestimate, double std_dev)
Function called by NSE.
void * core_connects(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
Callback for core.
static int valid_peers_iterator(void *cls, const struct GNUNET_PeerIdentity *peer)
Iterator function over stored, valid peers.
static void error_cb(void *cls)
void core_disconnects(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Callback for core.
static int get_valid_peers(struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, PeersIterator iterator, void *it_cls)
Get all currently known, valid peer ids.
static void restore_valid_peers(const struct Sub *sub)
Restore the peers on disk to #valid_peers.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition cadet_api.c:897
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers, const struct GNUNET_CORE_ServiceInfo *service_info)
Connect to the core service.
Definition core_api.c:698
@ GNUNET_CORE_SERVICE_RPS
Identifier for rps (random peer sampling) service.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_get_peer_identity(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *dst)
Retrieve the identity of the host's peer.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
const char * GNUNET_error_type_to_string(enum GNUNET_ErrorType kind)
Convert error type to string.
enum GNUNET_GenericReturnValue GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
@ GNUNET_ERROR_TYPE_INFO
struct GNUNET_NSE_Handle * GNUNET_NSE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_NSE_Callback func, void *func_cls)
Connect to the network size estimation service.
Definition nse_api.c:164
struct GNUNET_PEERSTORE_Monitor * GNUNET_PEERSTORE_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, int iterate_first, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Request watching a given key The monitoring can be filtered to contain only records matching peer and...
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
Gnunet service info - identifying compatibility with a range of version of a service communicating ov...
enum GNUNET_CORE_Service service
Identifier of the service on top of CORE.

References alpha, beta, cadet_handle, cfg, core_connects(), core_disconnects(), core_handle, core_init(), error_cb(), get_valid_peers(), GNUNET_APPLICATION_PORT_RPS, GNUNET_assert, GNUNET_CADET_connect(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CORE_connect(), GNUNET_CORE_SERVICE_RPS, GNUNET_CRYPTO_get_peer_identity(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_error_type_to_string(), GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_setup(), GNUNET_NSE_connect(), GNUNET_OK, GNUNET_PEERSTORE_connect(), GNUNET_PEERSTORE_HELLO_KEY, GNUNET_PEERSTORE_monitor_start(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_YES, LOG, msub, new_sub(), nse, nse_callback(), own_identity, peerstore, peerstore_notify, process_peerinfo_peers(), restore_valid_peers(), GNUNET_CORE_ServiceInfo::service, service, shutdown_task, stats, sync_cb(), Sub::valid_peers, and valid_peers_iterator().

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

Definition at line 457 of file gnunet-service-rps.c.

Referenced by new_sub(), and run().

◆ stats

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle

Handler to CADET.

Cadet channel for creating outbound channels.

Definition at line 467 of file gnunet-service-rps.c.

Referenced by get_channel(), GSF_cadet_start_server(), GSF_cadet_stop_server(), new_sub(), run(), and shutdown_task().

◆ core_handle

struct GNUNET_CORE_Handle* core_handle

Handle to CORE.

Definition at line 472 of file gnunet-service-rps.c.

Referenced by run(), and shutdown_task().

◆ map_single_hop

◆ own_identity

struct GNUNET_PeerIdentity own_identity
static

Our own identity.

Definition at line 482 of file gnunet-service-rps.c.

Referenced by run().

◆ alpha

float alpha
static

Percentage of total peer number in the view to send random PUSHes to.

Definition at line 488 of file gnunet-service-rps.c.

Referenced by checkvec(), do_round(), GNUNET_CRYPTO_cs_blinding_secrets_derive(), output_vectors(), and run().

◆ beta

float beta
static

Percentage of total peer number in the view to send random PULLs to.

Definition at line 494 of file gnunet-service-rps.c.

Referenced by checkvec(), do_round(), GNUNET_CRYPTO_cs_blinding_secrets_derive(), insert_decrypt_element(), output_vectors(), and run().

◆ nse

struct GNUNET_NSE_Handle* nse
static

Handler to NSE.

Definition at line 499 of file gnunet-service-rps.c.

Referenced by run(), and shutdown_task().

◆ peerstore

struct GNUNET_PEERSTORE_Handle* peerstore
static

Handle to the PEERSTORE service.

Definition at line 504 of file gnunet-service-rps.c.

Referenced by run(), and shutdown_task().

◆ peerstore_notify

struct GNUNET_PEERSTORE_Monitor* peerstore_notify
static

Our peerstore notification context.

We use notification to instantly learn about new peers as they are discovered.

Definition at line 510 of file gnunet-service-rps.c.

Referenced by process_peerinfo_peers(), run(), and shutdown_task().

◆ msub

◆ num_valid_peers_max

const uint32_t num_valid_peers_max = UINT32_MAX
static

Maximum number of valid peers to keep.

TODO read from config

Definition at line 591 of file gnunet-service-rps.c.

Referenced by add_valid_peer().

◆ cli_ctx_head

struct ClientContext* cli_ctx_head

◆ cli_ctx_tail

struct ClientContext* cli_ctx_tail

Definition at line 2132 of file gnunet-service-rps.c.

Referenced by client_connect_cb(), and destroy_cli_ctx().