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

Functions

static void do_round (void *cls)
 Send out PUSHes and PULLs, possibly update #view, samplers. More...
 
static struct PeerContextget_peer_ctx (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map, const struct GNUNET_PeerIdentity *peer)
 Get the PeerContext associated with a peer. More...
 
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. More...
 
static struct PeerContextcreate_peer_ctx (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Create a new PeerContext and insert it into the peer map. More...
 
static struct PeerContextcreate_or_get_peer_ctx (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Create or get a PeerContext. More...
 
static int check_connected (struct PeerContext *peer_ctx)
 Check whether we have a connection to this peer. More...
 
static int get_rand_peer_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Iterator function for get_random_peer_from_peermap. More...
 
static const struct GNUNET_PeerIdentityget_random_peer_from_peermap (struct GNUNET_CONTAINER_MultiPeerMap *valid_peers)
 Get a random peer from peer_map. More...
 
static int add_valid_peer (const struct GNUNET_PeerIdentity *peer, struct GNUNET_CONTAINER_MultiPeerMap *valid_peers)
 Add a given peer to valid peers. More...
 
static void remove_pending_message (struct PendingMessage *pending_msg, int cancel)
 Remove a pending message from the respective DLL. More...
 
static void set_peer_online (struct PeerContext *peer_ctx)
 Set the peer flag to living and call the pending operations on this peer. More...
 
static void cleanup_destroyed_channel (void *cls, const struct GNUNET_CADET_Channel *channel)
 This is called when a channel is destroyed. More...
 
static void handle_peer_check (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle a CHECK_LIVE message from another peer. More...
 
static void handle_peer_push (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle a PUSH message from another peer. More...
 
static void handle_peer_pull_request (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle PULL REQUEST request message from another peer. More...
 
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. More...
 
static void handle_peer_pull_reply (void *cls, const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
 Handle PULL REPLY message from another peer. More...
 
static struct ChannelCtxadd_channel_ctx (struct PeerContext *peer_ctx)
 Allocate memory for a new channel context and insert it into DLL. More...
 
static void remove_channel_ctx (struct ChannelCtx *channel_ctx)
 Free memory and NULL pointers. More...
 
struct GNUNET_CADET_Channelget_channel (struct PeerContext *peer_ctx)
 Get the channel of a peer. More...
 
static struct GNUNET_MQ_Handleget_mq (struct PeerContext *peer_ctx)
 Get the message queue (GNUNET_MQ_Handle) of a specific peer. More...
 
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. More...
 
static void mq_online_check_successful (void *cls)
 This is called in response to the first message we sent as a online check. More...
 
static void check_peer_online (struct PeerContext *peer_ctx)
 Issue a check whether peer is online. More...
 
static int check_operation_scheduled (const struct PeerContext *peer_ctx, const PeerOp peer_op)
 Check whether function of type PeerOp was already scheduled. More...
 
static void destroy_channel (struct ChannelCtx *channel_ctx)
 Callback for scheduler to destroy a channel. More...
 
static void destroy_channel_cb (void *cls)
 Destroy a cadet channel. More...
 
static void schedule_channel_destruction (struct ChannelCtx *channel_ctx)
 Schedule the destruction of a channel for immediately afterwards. More...
 
static int destroy_peer (struct PeerContext *peer_ctx)
 Remove peer. More...
 
static int peermap_clear_iterator (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Iterator over hash map entries. More...
 
static void mq_notify_sent_cb (void *cls)
 This is called once a message is sent. More...
 
static int store_peer_presistently_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Iterator function for store_valid_peers. More...
 
static void store_valid_peers (const struct Sub *sub)
 Store the peers currently in #valid_peers to disk. More...
 
static const struct GNUNET_PeerIdentitys2i_full (const char *string_repr)
 Convert string representation of peer id to peer id. More...
 
static void restore_valid_peers (const struct Sub *sub)
 Restore the peers on disk to #valid_peers. More...
 
static void peers_terminate (struct Sub *sub)
 Delete storage of peers that was created with #initialise_peers () More...
 
static int valid_peer_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Iterator over #valid_peers hash map entries. More...
 
static int get_valid_peers (struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, PeersIterator iterator, void *it_cls)
 Get all currently known, valid peer ids. More...
 
static int insert_peer (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Add peer to known peers. More...
 
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. More...
 
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. More...
 
static int check_removable (const struct PeerContext *peer_ctx)
 Check if peer is removable. More...
 
static int check_peer_valid (const struct GNUNET_CONTAINER_MultiPeerMap *valid_peers, const struct GNUNET_PeerIdentity *peer)
 Check whether peer is actually a peer. More...
 
static void indicate_sending_intention (struct PeerContext *peer_ctx)
 Indicate that we want to send to the other peer. More...
 
static int check_peer_send_intention (const struct PeerContext *peer_ctx)
 Check whether other peer has the intention to send/opened channel towars us. More...
 
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. More...
 
static int check_sending_channel_exists (const struct PeerContext *peer_ctx)
 Check whether a sending channel towards the given peer exists. More...
 
static int destroy_sending_channel (struct PeerContext *peer_ctx)
 Destroy the send channel of a peer e.g. More...
 
static void send_message (struct PeerContext *peer_ctx, struct GNUNET_MQ_Envelope *ev, const char *type)
 Send a message to another peer. More...
 
static int schedule_operation (struct PeerContext *peer_ctx, const PeerOp peer_op, void *cls)
 Schedule a operation on given peer. More...
 
static void print_peer_list (struct GNUNET_PeerIdentity *list, unsigned int len)
 Print peerlist to log. More...
 
static void rem_from_list (struct GNUNET_PeerIdentity **peer_list, unsigned int *list_size, const struct GNUNET_PeerIdentity *peer)
 Remove peer from list. More...
 
static void insert_in_view_op (void *cls, const struct GNUNET_PeerIdentity *peer)
 Insert PeerID in #view. More...
 
static int insert_in_view (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Insert PeerID in #view. More...
 
static void send_view (const struct ClientContext *cli_ctx, const struct GNUNET_PeerIdentity *view_array, uint64_t view_size)
 Send view to client. More...
 
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. More...
 
static void clients_notify_view_update (const struct Sub *sub)
 sends updates to clients that are interested More...
 
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 More...
 
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. More...
 
static void resize_wrapper (struct RPS_Sampler *sampler, uint32_t new_size)
 Wrapper around RPS_sampler_resize() More...
 
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. More...
 
static void insert_in_pull_map (void *cls, const struct GNUNET_PeerIdentity *peer)
 Insert PeerID in #pull_map. More...
 
static void insert_in_sampler (void *cls, const struct GNUNET_PeerIdentity *peer)
 Update sampler with given PeerID. More...
 
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. More...
 
static int check_sending_channel_needed (const struct PeerContext *peer_ctx)
 Checks if there is a sending channel and if it is needed. More...
 
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. More...
 
static void clean_peer (struct Sub *sub, const struct GNUNET_PeerIdentity *peer)
 Remove data that is not needed anymore. More...
 
struct Subnew_sub (const struct GNUNET_HashCode *hash, uint32_t sampler_size, struct GNUNET_TIME_Relative round_interval)
 Create a new Sub. More...
 
static void destroy_sub (struct Sub *sub)
 Destroy Sub. More...
 
void core_init (void *cls, const struct GNUNET_PeerIdentity *my_identity)
 Callback on initialisation of Core. More...
 
void * core_connects (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
 Callback for core. More...
 
void core_disconnects (void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
 Callback for core. More...
 
static void destroy_cli_ctx (struct ClientContext *cli_ctx)
 Destroy the context for a (connected) client. More...
 
static void adapt_sizes (struct Sub *sub, double logestimate, double std_dev)
 Update sizes in sampler and view on estimate update from nse service. More...
 
static void nse_callback (void *cls, struct GNUNET_TIME_Absolute timestamp, double logestimate, double std_dev)
 Function called by NSE. More...
 
static int check_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg)
 This function is called, when the client seeds peers. More...
 
static void handle_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg)
 Handle seed from the client. More...
 
static void handle_client_view_request (void *cls, const struct GNUNET_RPS_CS_DEBUG_ViewRequest *msg)
 Handle RPS request from the client. More...
 
static void handle_client_view_cancel (void *cls, const struct GNUNET_MessageHeader *msg)
 Handle the cancellation of the view updates. More...
 
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. More...
 
static void handle_client_stream_cancel (void *cls, const struct GNUNET_MessageHeader *msg)
 Handles the cancellation of the stream of biased peer ids. More...
 
static void handle_client_start_sub (void *cls, const struct GNUNET_RPS_CS_SubStartMessage *msg)
 Create and start a Sub. More...
 
static void handle_client_stop_sub (void *cls, const struct GNUNET_RPS_CS_SubStopMessage *msg)
 Destroy the Sub. More...
 
static struct GNUNET_TIME_Relative compute_rand_delay (struct GNUNET_TIME_Relative mean, unsigned int spread)
 Compute a random delay. More...
 
static void send_pull_request (struct PeerContext *peer_ctx)
 Send single pull request. More...
 
static void send_push (struct PeerContext *peer_ctx)
 Send single push. More...
 
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(). More...
 
static int valid_peers_iterator (void *cls, const struct GNUNET_PeerIdentity *peer)
 Iterator function over stored, valid peers. More...
 
void process_peerinfo_peers (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Iterator over peers from peerinfo. More...
 
static void shutdown_task (void *cls)
 Task run during shutdown. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 Handle client connecting to the service. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls)
 Callback called when a client disconnected from the service. More...
 
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. More...
 
 GNUNET_SERVICE_MAIN ("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. More...
 

Variables

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

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

◆ 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 4285 of file gnunet-service-rps.c.

4286{
4287 unsigned int i;
4288 const struct GNUNET_PeerIdentity *view_array;
4289 unsigned int *permut;
4290 unsigned int a_peers; /* Number of peers we send pushes to */
4291 unsigned int b_peers; /* Number of peers we send pull requests to */
4292 uint32_t first_border;
4293 uint32_t second_border;
4294 struct GNUNET_PeerIdentity peer;
4295 struct GNUNET_PeerIdentity *update_peer;
4296 struct Sub *sub = cls;
4297
4298 sub->num_rounds++;
4300 "Going to execute next round.\n");
4301 if (sub == msub)
4302 {
4303 GNUNET_STATISTICS_update (stats, "# rounds", 1, GNUNET_NO);
4304 }
4305 sub->do_round_task = NULL;
4306#ifdef TO_FILE_FULL
4307 to_file (sub->file_name_view_log,
4308 "___ new round ___");
4309#endif /* TO_FILE_FULL */
4310 view_array = View_get_as_array (sub->view);
4311 for (i = 0; i < View_size (sub->view); i++)
4312 {
4314 "\t%s\n", GNUNET_i2s (&view_array[i]));
4315#ifdef TO_FILE_FULL
4316 to_file (sub->file_name_view_log,
4317 "=%s\t(do round)",
4318 GNUNET_i2s_full (&view_array[i]));
4319#endif /* TO_FILE_FULL */
4320 }
4321
4322
4323 /* Send pushes and pull requests */
4324 if (0 < View_size (sub->view))
4325 {
4327 View_size (sub->view));
4328
4329 /* Send PUSHes */
4330 a_peers = ceil (alpha * View_size (sub->view));
4331
4333 "Going to send pushes to %u (ceil (%f * %u)) peers.\n",
4334 a_peers, alpha, View_size (sub->view));
4335 for (i = 0; i < a_peers; i++)
4336 {
4337 peer = view_array[permut[i]];
4338 // FIXME if this fails schedule/loop this for later
4339 send_push (get_peer_ctx (sub->peer_map, &peer));
4340 }
4341
4342 /* Send PULL requests */
4343 b_peers = ceil (beta * View_size (sub->view));
4344 first_border = a_peers;
4345 second_border = a_peers + b_peers;
4346 if (second_border > View_size (sub->view))
4347 {
4348 first_border = View_size (sub->view) - b_peers;
4349 second_border = View_size (sub->view);
4350 }
4352 "Going to send pulls to %u (ceil (%f * %u)) peers.\n",
4353 b_peers, beta, View_size (sub->view));
4354 for (i = first_border; i < second_border; i++)
4355 {
4356 peer = view_array[permut[i]];
4357 if (GNUNET_NO == check_peer_flag (sub->peer_map,
4358 &peer,
4360 { // FIXME if this fails schedule/loop this for later
4361 send_pull_request (get_peer_ctx (sub->peer_map, &peer));
4362 }
4363 }
4364
4365 GNUNET_free (permut);
4366 permut = NULL;
4367 }
4368
4369
4370 /* Update view */
4371 /* TODO see how many peers are in push-/pull- list! */
4372
4373 if ((CustomPeerMap_size (sub->push_map) <= alpha * sub->view_size_est_need) &&
4374 (0 < CustomPeerMap_size (sub->push_map)) &&
4375 (0 < CustomPeerMap_size (sub->pull_map)))
4376 { /* If conditions for update are fulfilled, update */
4377 LOG (GNUNET_ERROR_TYPE_DEBUG, "Update of the view.\n");
4378
4379 uint32_t final_size;
4380 uint32_t peers_to_clean_size;
4381 struct GNUNET_PeerIdentity *peers_to_clean;
4382
4383 peers_to_clean = NULL;
4384 peers_to_clean_size = 0;
4385 GNUNET_array_grow (peers_to_clean,
4386 peers_to_clean_size,
4387 View_size (sub->view));
4388 GNUNET_memcpy (peers_to_clean,
4389 view_array,
4390 View_size (sub->view) * sizeof(struct GNUNET_PeerIdentity));
4391
4392 /* Seems like recreating is the easiest way of emptying the peermap */
4393 View_clear (sub->view);
4394#ifdef TO_FILE_FULL
4395 to_file (sub->file_name_view_log,
4396 "--- emptied ---");
4397#endif /* TO_FILE_FULL */
4398
4399 first_border = GNUNET_MIN (ceil (alpha * sub->view_size_est_need),
4401 second_border = first_border
4402 + GNUNET_MIN (floor (beta * sub->view_size_est_need),
4404 final_size = second_border
4405 + ceil ((1 - (alpha + beta)) * sub->view_size_est_need);
4407 "first border: %" PRIu32 ", second border: %" PRIu32 ", final size: %"
4408 PRIu32 "\n",
4409 first_border,
4410 second_border,
4411 final_size);
4412
4413 /* Update view with peers received through PUSHes */
4416 for (i = 0; i < first_border; i++)
4417 {
4418 int inserted;
4419 inserted = insert_in_view (sub,
4421 permut[i]));
4422 if (GNUNET_OK == inserted)
4423 {
4425 1,
4427 sub->push_map, permut[i]));
4428 }
4429#ifdef TO_FILE_FULL
4430 to_file (sub->file_name_view_log,
4431 "+%s\t(push list)",
4432 GNUNET_i2s_full (&view_array[i]));
4433#endif /* TO_FILE_FULL */
4434 // TODO change the peer_flags accordingly
4435 }
4436 GNUNET_free (permut);
4437 permut = NULL;
4438
4439 /* Update view with peers received through PULLs */
4442 for (i = first_border; i < second_border; i++)
4443 {
4444 int inserted;
4445 inserted = insert_in_view (sub,
4447 permut[i
4448 -
4449 first_border
4450 ]));
4451 if (GNUNET_OK == inserted)
4452 {
4454 1,
4456 sub->pull_map,
4457 permut[i
4458 - first_border]));
4459 }
4460#ifdef TO_FILE_FULL
4461 to_file (sub->file_name_view_log,
4462 "+%s\t(pull list)",
4463 GNUNET_i2s_full (&view_array[i]));
4464#endif /* TO_FILE_FULL */
4465 // TODO change the peer_flags accordingly
4466 }
4467 GNUNET_free (permut);
4468 permut = NULL;
4469
4470 /* Update view with peers from history */
4472 final_size - second_border,
4474 sub);
4475 // TODO change the peer_flags accordingly
4476
4477 for (i = 0; i < View_size (sub->view); i++)
4478 rem_from_list (&peers_to_clean, &peers_to_clean_size, &view_array[i]);
4479
4480 /* Clean peers that were removed from the view */
4481 for (i = 0; i < peers_to_clean_size; i++)
4482 {
4483#ifdef TO_FILE_FULL
4484 to_file (sub->file_name_view_log,
4485 "-%s",
4486 GNUNET_i2s_full (&peers_to_clean[i]));
4487#endif /* TO_FILE_FULL */
4488 clean_peer (sub, &peers_to_clean[i]);
4489 }
4490
4491 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0);
4493 }
4494 else
4495 {
4496 LOG (GNUNET_ERROR_TYPE_DEBUG, "No update of the view.\n");
4497 if (sub == msub)
4498 {
4499 GNUNET_STATISTICS_update (stats, "# rounds blocked", 1, GNUNET_NO);
4500 if ((CustomPeerMap_size (sub->push_map) > alpha
4501 * sub->view_size_est_need) &&
4502 ! (0 >= CustomPeerMap_size (sub->pull_map)))
4503 GNUNET_STATISTICS_update (stats, "# rounds blocked - too many pushes",
4504 1, GNUNET_NO);
4505 if ((CustomPeerMap_size (sub->push_map) > alpha
4506 * sub->view_size_est_need) &&
4507 (0 >= CustomPeerMap_size (sub->pull_map)))
4509 "# rounds blocked - too many pushes, no pull replies",
4510 1, GNUNET_NO);
4511 if ((0 >= CustomPeerMap_size (sub->push_map)) &&
4512 ! (0 >= CustomPeerMap_size (sub->pull_map)))
4513 GNUNET_STATISTICS_update (stats, "# rounds blocked - no pushes", 1,
4514 GNUNET_NO);
4515 if ((0 >= CustomPeerMap_size (sub->push_map)) &&
4516 (0 >= CustomPeerMap_size (sub->pull_map)))
4518 "# rounds blocked - no pushes, no pull replies",
4519 1, GNUNET_NO);
4520 if ((0 >= CustomPeerMap_size (sub->pull_map)) &&
4522 * sub->view_size_est_need) &&
4523 (0 >= CustomPeerMap_size (sub->push_map)) )
4524 GNUNET_STATISTICS_update (stats, "# rounds blocked - no pull replies",
4525 1, GNUNET_NO);
4526 }
4527 }
4528 // TODO independent of that also get some peers from CADET_get_peers()?
4530 {
4531 sub->push_recv[CustomPeerMap_size (sub->push_map)]++;
4532 }
4533 else
4534 {
4536 "Push map size too big for histogram (%u, %u)\n",
4539 }
4540 // FIXME check bounds of histogram
4541 sub->push_delta[(int32_t) (CustomPeerMap_size (sub->push_map)
4542 - (alpha * sub->view_size_est_need))
4543 + (HISTOGRAM_FILE_SLOTS / 2)]++;
4544 if (sub == msub)
4545 {
4547 "# peers in push map at end of round",
4549 GNUNET_NO);
4551 "# peers in pull map at end of round",
4553 GNUNET_NO);
4555 "# peers in view at end of round",
4556 View_size (sub->view),
4557 GNUNET_NO);
4559 "# expected pushes",
4561 GNUNET_NO);
4563 "delta expected - received pushes",
4565 * sub->
4566 view_size_est_need),
4567 GNUNET_NO);
4568 }
4569
4571 "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (sub->view%u) = %.2f)\n",
4574 alpha,
4575 View_size (sub->view),
4576 alpha * View_size (sub->view));
4577
4578 /* Update samplers */
4579 for (i = 0; i < CustomPeerMap_size (sub->push_map); i++)
4580 {
4581 update_peer = CustomPeerMap_get_peer_by_index (sub->push_map, i);
4583 "Updating with peer %s from push list\n",
4584 GNUNET_i2s (update_peer));
4585 insert_in_sampler (sub, update_peer);
4586 clean_peer (sub, update_peer); /* This cleans only if it is not in the view */
4587 }
4588
4589 for (i = 0; i < CustomPeerMap_size (sub->pull_map); i++)
4590 {
4592 "Updating with peer %s from pull list\n",
4595 /* This cleans only if it is not in the view */
4597 }
4598
4599
4600 /* Empty push/pull lists */
4603
4604 if (sub == msub)
4605 {
4607 "view size",
4608 View_size (sub->view),
4609 GNUNET_NO);
4610 }
4611
4612 struct GNUNET_TIME_Relative time_next_round;
4613
4614 time_next_round = compute_rand_delay (sub->round_interval, 2);
4615
4616 /* Schedule next round */
4617 sub->do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round,
4618 &do_round, sub);
4619 LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished round\n");
4620}
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
@ GNUNET_NO
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:1278
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.
Definition: rps-test_util.h:65
@ 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:94
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 valid_peers));
816 (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
818 iterator_cls);
819 ret = iterator_cls->peer;
820 GNUNET_free (iterator_cls);
821 return ret;
822}
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 837 of file gnunet-service-rps.c.

839{
840 const struct GNUNET_PeerIdentity *rand_peer;
841 int ret;
842
843 ret = GNUNET_YES;
844 /* Remove random peers until there is space for a new one */
845 while (num_valid_peers_max <=
847 {
848 rand_peer = get_random_peer_from_peermap (valid_peers);
849 GNUNET_CONTAINER_multipeermap_remove_all (valid_peers, rand_peer);
850 ret = GNUNET_NO;
851 }
852 (void) GNUNET_CONTAINER_multipeermap_put (valid_peers, peer, NULL,
854 if (valid_peers == msub->valid_peers)
855 {
857 "# valid peers",
859 GNUNET_NO);
860 }
861 return ret;
862}
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 1091 of file gnunet-service-rps.c.

1092{
1093 struct PeerContext *peer_ctx;
1094
1095 (void) cancel;
1096
1097 peer_ctx = pending_msg->peer_ctx;
1098 GNUNET_assert (NULL != peer_ctx);
1100 peer_ctx->pending_messages_tail,
1101 pending_msg);
1102 // TODO wait for the cadet implementation of message cancellation
1103 // if (GNUNET_YES == cancel)
1104 // {
1105 // GNUNET_MQ_send_cancel (pending_msg->ev);
1106 // }
1107 GNUNET_free (pending_msg);
1108}
#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 877 of file gnunet-service-rps.c.

878{
879 struct GNUNET_PeerIdentity *peer;
880 unsigned int i;
881
882 peer = &peer_ctx->peer_id;
884 "Peer %s is online and valid, calling %i pending operations on it\n",
885 GNUNET_i2s (peer),
886 peer_ctx->num_pending_ops);
887
888 if (NULL != peer_ctx->online_check_pending)
889 {
891 "Removing pending online check for peer %s\n",
892 GNUNET_i2s (&peer_ctx->peer_id));
893 // TODO wait until cadet sets mq->cancel_impl
894 // GNUNET_MQ_send_cancel (peer_ctx->online_check_pending->ev);
896 peer_ctx->online_check_pending = NULL;
897 }
898
899 SET_PEER_FLAG (peer_ctx, Peers_ONLINE);
900
901 /* Call pending operations */
902 for (i = 0; i < peer_ctx->num_pending_ops; i++)
903 {
904 peer_ctx->pending_ops[i].op (peer_ctx->pending_ops[i].op_cls, peer);
905 }
906 GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0);
907}
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 2834 of file gnunet-service-rps.c.

2836{
2837 struct ChannelCtx *channel_ctx = cls;
2838 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
2839
2840 (void) channel;
2841
2842 channel_ctx->channel = NULL;
2843 if ((NULL != peer_ctx) &&
2844 (peer_ctx->send_channel_ctx == channel_ctx) &&
2846 {
2847 remove_channel_ctx (channel_ctx);
2848 remove_peer (peer_ctx->sub, &peer_ctx->peer_id);
2849 }
2850 else
2851 {
2852 /* We need this if-else construct because we need to make sure the channel
2853 * (context) is cleaned up before removing the peer, but still need to
2854 * compare it while checking the condition */
2855 remove_channel_ctx (channel_ctx);
2856 }
2857}
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 3529 of file gnunet-service-rps.c.

3531{
3532 const struct ChannelCtx *channel_ctx = cls;
3533 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3534
3535 (void) msg;
3536
3538 "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer));
3539 if (channel_ctx->peer_ctx->sub == msub)
3540 {
3542 "# pending online checks",
3543 -1,
3544 GNUNET_NO);
3545 }
3546
3547 GNUNET_CADET_receive_done (channel_ctx->channel);
3548}
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:872

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 3561 of file gnunet-service-rps.c.

3563{
3564 const struct ChannelCtx *channel_ctx = cls;
3565 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3566
3567 (void) msg;
3568
3569 // (check the proof of work (?))
3570
3572 "Received PUSH (%s)\n",
3573 GNUNET_i2s (peer));
3574 if (channel_ctx->peer_ctx->sub == msub)
3575 {
3576 GNUNET_STATISTICS_update (stats, "# push message received", 1, GNUNET_NO);
3577 if ((NULL != map_single_hop) &&
3579 peer)))
3580 {
3582 "# push message received (multi-hop peer)",
3583 1,
3584 GNUNET_NO);
3585 }
3586 }
3587
3588 #if ENABLE_MALICIOUS
3589 struct AttackedPeer *tmp_att_peer;
3590
3591 if ((1 == mal_type) ||
3592 (3 == mal_type))
3593 { /* Try to maximise representation */
3594 tmp_att_peer = GNUNET_new (struct AttackedPeer);
3595 tmp_att_peer->peer_id = *peer;
3596 if (NULL == att_peer_set)
3599 peer))
3600 {
3601 GNUNET_CONTAINER_DLL_insert (att_peers_head,
3602 att_peers_tail,
3603 tmp_att_peer);
3604 add_peer_array_to_set (peer, 1, att_peer_set);
3605 }
3606 else
3607 {
3608 GNUNET_free (tmp_att_peer);
3609 }
3610 }
3611
3612
3613 else if (2 == mal_type)
3614 {
3615 /* We attack one single well-known peer - simply ignore */
3616 }
3617 #endif /* ENABLE_MALICIOUS */
3618
3619 /* Add the sending peer to the push_map */
3620 CustomPeerMap_put (channel_ctx->peer_ctx->sub->push_map, peer);
3621
3623 &channel_ctx->peer_ctx->peer_id));
3624 GNUNET_CADET_receive_done (channel_ctx->channel);
3625}
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 3637 of file gnunet-service-rps.c.

3639{
3640 const struct ChannelCtx *channel_ctx = cls;
3641 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
3642 const struct GNUNET_PeerIdentity *peer = &peer_ctx->peer_id;
3643 const struct GNUNET_PeerIdentity *view_array;
3644
3645 (void) msg;
3646
3647 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (
3648 peer));
3649 if (peer_ctx->sub == msub)
3650 {
3652 "# pull request message received",
3653 1,
3654 GNUNET_NO);
3655 if ((NULL != map_single_hop) &&
3657 &peer_ctx->peer_id)))
3658 {
3660 "# pull request message received (multi-hop peer)",
3661 1,
3662 GNUNET_NO);
3663 }
3664 }
3665
3666 #if ENABLE_MALICIOUS
3667 if ((1 == mal_type)
3668 || (3 == mal_type))
3669 { /* Try to maximise representation */
3670 send_pull_reply (peer_ctx, mal_peers, num_mal_peers);
3671 }
3672
3673 else if (2 == mal_type)
3674 { /* Try to partition network */
3675 if (0 == GNUNET_memcmp (&attacked_peer, peer))
3676 {
3677 send_pull_reply (peer_ctx, mal_peers, num_mal_peers);
3678 }
3679 }
3680 #endif /* ENABLE_MALICIOUS */
3681
3683 &channel_ctx->peer_ctx->peer_id));
3684 GNUNET_CADET_receive_done (channel_ctx->channel);
3685 view_array = View_get_as_array (channel_ctx->peer_ctx->sub->view);
3686 send_pull_reply (peer_ctx,
3687 view_array,
3688 View_size (channel_ctx->peer_ctx->sub->view));
3689}
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 3700 of file gnunet-service-rps.c.

3702{
3703 struct ChannelCtx *channel_ctx = cls;
3704 struct PeerContext *sender_ctx = channel_ctx->peer_ctx;
3705
3706 if (sizeof(struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->header.size))
3707 {
3708 GNUNET_break_op (0);
3709 return GNUNET_SYSERR;
3710 }
3711
3712 if ((ntohs (msg->header.size) - sizeof(struct
3714 / sizeof(struct GNUNET_PeerIdentity) != ntohl (msg->num_peers))
3715 {
3717 "message says it sends %" PRIu32 " peers, have space for %lu peers\n",
3718 ntohl (msg->num_peers),
3719 (ntohs (msg->header.size) - sizeof(struct
3721 / sizeof(struct GNUNET_PeerIdentity));
3722 GNUNET_break_op (0);
3723 return GNUNET_SYSERR;
3724 }
3725
3726 if (GNUNET_YES != check_peer_flag (sender_ctx->sub->peer_map,
3727 &sender_ctx->peer_id,
3729 {
3731 "Received a pull reply from a peer (%s) we didn't request one from!\n",
3732 GNUNET_i2s (&sender_ctx->peer_id));
3733 if (sender_ctx->sub == msub)
3734 {
3736 "# unrequested pull replies",
3737 1,
3738 GNUNET_NO);
3739 }
3740 }
3741 return GNUNET_OK;
3742}
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_ERROR
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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 3752 of file gnunet-service-rps.c.

3754{
3755 const struct ChannelCtx *channel_ctx = cls;
3756 const struct GNUNET_PeerIdentity *sender = &channel_ctx->peer_ctx->peer_id;
3757 const struct GNUNET_PeerIdentity *peers;
3758 struct Sub *sub = channel_ctx->peer_ctx->sub;
3759 uint32_t i;
3760
3761#if ENABLE_MALICIOUS
3762 struct AttackedPeer *tmp_att_peer;
3763#endif /* ENABLE_MALICIOUS */
3764
3765 sub->pull_delays[sub->num_rounds - channel_ctx->peer_ctx->round_pull_req]++;
3766 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REPLY (%s)\n", GNUNET_i2s (
3767 sender));
3768 if (channel_ctx->peer_ctx->sub == msub)
3769 {
3771 "# pull reply messages received",
3772 1,
3773 GNUNET_NO);
3774 if ((NULL != map_single_hop) &&
3776 &channel_ctx->
3777 peer_ctx->peer_id)) )
3778 {
3780 "# pull reply messages received (multi-hop peer)",
3781 1,
3782 GNUNET_NO);
3783 }
3784 }
3785
3786 #if ENABLE_MALICIOUS
3787 // We shouldn't even receive pull replies as we're not sending
3788 if (2 == mal_type)
3789 {
3790 }
3791 #endif /* ENABLE_MALICIOUS */
3792
3793 /* Do actual logic */
3794 peers = (const struct GNUNET_PeerIdentity *) &msg[1];
3795
3797 "PULL REPLY received, got following %u peers:\n",
3798 ntohl (msg->num_peers));
3799
3800 for (i = 0; i < ntohl (msg->num_peers); i++)
3801 {
3803 "%u. %s\n",
3804 i,
3805 GNUNET_i2s (&peers[i]));
3806
3807 #if ENABLE_MALICIOUS
3808 if ((NULL != att_peer_set) &&
3809 ((1 == mal_type) || (3 == mal_type) ))
3810 { /* Add attacked peer to local list */
3811 // TODO check if we sent a request and this was the first reply
3813 &peers[i]))
3815 &peers[i])) )
3816 {
3817 tmp_att_peer = GNUNET_new (struct AttackedPeer);
3818 tmp_att_peer->peer_id = peers[i];
3819 GNUNET_CONTAINER_DLL_insert (att_peers_head,
3820 att_peers_tail,
3821 tmp_att_peer);
3822 add_peer_array_to_set (&peers[i], 1, att_peer_set);
3823 }
3824 continue;
3825 }
3826 #endif /* ENABLE_MALICIOUS */
3827 /* Make sure we 'know' about this peer */
3828 (void) insert_peer (channel_ctx->peer_ctx->sub,
3829 &peers[i]);
3830
3831 if (GNUNET_YES == check_peer_valid (channel_ctx->peer_ctx->sub->valid_peers,
3832 &peers[i]))
3833 {
3834 CustomPeerMap_put (channel_ctx->peer_ctx->sub->pull_map,
3835 &peers[i]);
3836 }
3837 else
3838 {
3839 schedule_operation (channel_ctx->peer_ctx,
3841 channel_ctx->peer_ctx->sub); /* cls */
3842 (void) issue_peer_online_check (channel_ctx->peer_ctx->sub,
3843 &peers[i]);
3844 }
3845 }
3846
3848 sender),
3850 clean_peer (channel_ctx->peer_ctx->sub,
3851 sender);
3852
3854 sender));
3855 GNUNET_CADET_receive_done (channel_ctx->channel);
3856}
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 945 of file gnunet-service-rps.c.

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

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 961 of file gnunet-service-rps.c.

962{
963 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
964
965 if (NULL != channel_ctx->destruction_task)
966 {
968 channel_ctx->destruction_task = NULL;
969 }
970
971 if (NULL == peer_ctx)
972 return;
973 if (channel_ctx == peer_ctx->send_channel_ctx)
974 {
975 peer_ctx->send_channel_ctx = NULL;
976 peer_ctx->mq = NULL;
977 }
978 else if (channel_ctx == peer_ctx->recv_channel_ctx)
979 {
980 peer_ctx->recv_channel_ctx = NULL;
981 }
982 GNUNET_free (channel_ctx);
983}
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
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 993 of file gnunet-service-rps.c.

994{
995 /* There exists a copy-paste-clone in run() */
996 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
997 GNUNET_MQ_hd_fixed_size (peer_check,
1000 NULL),
1001 GNUNET_MQ_hd_fixed_size (peer_push,
1003 struct GNUNET_MessageHeader,
1004 NULL),
1005 GNUNET_MQ_hd_fixed_size (peer_pull_request,
1007 struct GNUNET_MessageHeader,
1008 NULL),
1009 GNUNET_MQ_hd_var_size (peer_pull_reply,
1012 NULL),
1014 };
1015
1016
1017 if (NULL == peer_ctx->send_channel_ctx)
1018 {
1020 "Trying to establish channel to peer %s\n",
1021 GNUNET_i2s (&peer_ctx->peer_id));
1022 peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx);
1023 peer_ctx->send_channel_ctx->channel =
1025 peer_ctx->send_channel_ctx, /* context */
1026 &peer_ctx->peer_id,
1027 &peer_ctx->sub->hash,
1028 NULL, /* WindowSize handler */
1029 &cleanup_destroyed_channel, /* Disconnect handler */
1030 cadet_handlers);
1031 }
1032 GNUNET_assert (NULL != peer_ctx->send_channel_ctx);
1033 GNUNET_assert (NULL != peer_ctx->send_channel_ctx->channel);
1034 return peer_ctx->send_channel_ctx->channel;
1035}
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:1015
#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 1048 of file gnunet-service-rps.c.

1049{
1050 if (NULL == peer_ctx->mq)
1051 {
1052 peer_ctx->mq = GNUNET_CADET_get_mq (get_channel (peer_ctx));
1053 }
1054 return peer_ctx->mq;
1055}
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:1066

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 1067 of file gnunet-service-rps.c.

1070{
1071 struct PendingMessage *pending_msg;
1072
1073 pending_msg = GNUNET_new (struct PendingMessage);
1074 pending_msg->ev = ev;
1075 pending_msg->peer_ctx = peer_ctx;
1076 pending_msg->type = type;
1079 pending_msg);
1080 return pending_msg;
1081}
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 1118 of file gnunet-service-rps.c.

1119{
1120 struct PeerContext *peer_ctx = cls;
1121
1122 if (NULL != peer_ctx->online_check_pending)
1123 {
1125 "Online check for peer %s was successful\n",
1126 GNUNET_i2s (&peer_ctx->peer_id));
1128 peer_ctx->online_check_pending = NULL;
1129 set_peer_online (peer_ctx);
1130 (void) add_valid_peer (&peer_ctx->peer_id, peer_ctx->sub->valid_peers);
1131 }
1132}
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 1141 of file gnunet-service-rps.c.

1142{
1144 "Get informed about peer %s getting online\n",
1145 GNUNET_i2s (&peer_ctx->peer_id));
1146
1147 struct GNUNET_MQ_Handle *mq;
1148 struct GNUNET_MQ_Envelope *ev;
1149
1151 peer_ctx->online_check_pending =
1152 insert_pending_message (peer_ctx, ev, "Check online");
1153 mq = get_mq (peer_ctx);
1156 peer_ctx);
1157 GNUNET_MQ_send (mq, ev);
1158 if (peer_ctx->sub == msub)
1159 {
1161 "# pending online checks",
1162 1,
1163 GNUNET_NO);
1164 }
1165}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
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:304
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:87
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:638
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 1181 of file gnunet-service-rps.c.

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

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 1199 of file gnunet-service-rps.c.

1200{
1201 struct GNUNET_CADET_Channel *channel;
1202
1203 if (NULL != channel_ctx->destruction_task)
1204 {
1206 channel_ctx->destruction_task = NULL;
1207 }
1208 GNUNET_assert (channel_ctx->channel != NULL);
1209 channel = channel_ctx->channel;
1210 channel_ctx->channel = NULL;
1212 remove_channel_ctx (channel_ctx);
1213}
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
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 1224 of file gnunet-service-rps.c.

1225{
1226 struct ChannelCtx *channel_ctx = cls;
1227
1228 channel_ctx->destruction_task = NULL;
1229 destroy_channel (channel_ctx);
1230}
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 1244 of file gnunet-service-rps.c.

1245{
1246 GNUNET_assert (NULL ==
1247 channel_ctx->destruction_task);
1248 GNUNET_assert (NULL !=
1249 channel_ctx->channel);
1250 channel_ctx->destruction_task =
1252 channel_ctx);
1253}
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:1305

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 1270 of file gnunet-service-rps.c.

1271{
1272 GNUNET_assert (NULL != peer_ctx);
1273 GNUNET_assert (NULL != peer_ctx->sub->peer_map);
1274 if (GNUNET_NO ==
1276 &peer_ctx->peer_id))
1277 {
1278 return GNUNET_NO;
1279 }
1280 SET_PEER_FLAG (peer_ctx, Peers_TO_DESTROY);
1282 "Going to remove peer %s\n",
1283 GNUNET_i2s (&peer_ctx->peer_id));
1284 UNSET_PEER_FLAG (peer_ctx, Peers_ONLINE);
1285
1286 /* Clear list of pending operations */
1287 // TODO this probably leaks memory
1288 // ('only' the cls to the function. Not sure what to do with it)
1289 GNUNET_array_grow (peer_ctx->pending_ops,
1290 peer_ctx->num_pending_ops,
1291 0);
1292 /* Remove all pending messages */
1293 while (NULL != peer_ctx->pending_messages_head)
1294 {
1296 "Removing unsent %s\n",
1297 peer_ctx->pending_messages_head->type);
1298 /* Cancel pending message, too */
1299 if ((NULL != peer_ctx->online_check_pending) &&
1300 (0 == memcmp (peer_ctx->pending_messages_head,
1301 peer_ctx->online_check_pending,
1302 sizeof(struct PendingMessage))))
1303 {
1304 peer_ctx->online_check_pending = NULL;
1305 if (peer_ctx->sub == msub)
1306 {
1308 "# pending online checks",
1309 -1,
1310 GNUNET_NO);
1311 }
1312 }
1314 GNUNET_YES);
1315 }
1316
1317 /* If we are still waiting for notification whether this peer is online
1318 * cancel the according task */
1319 if (NULL != peer_ctx->online_check_pending)
1320 {
1322 "Removing pending online check for peer %s\n",
1323 GNUNET_i2s (&peer_ctx->peer_id));
1324 // TODO wait until cadet sets mq->cancel_impl
1325 // GNUNET_MQ_send_cancel (peer_ctx->online_check_pending->ev);
1327 GNUNET_YES);
1328 peer_ctx->online_check_pending = NULL;
1329 }
1330
1331 if (NULL != peer_ctx->send_channel_ctx)
1332 {
1333 /* This is possibly called from within channel destruction */
1334 peer_ctx->send_channel_ctx->peer_ctx = NULL;
1336 peer_ctx->send_channel_ctx = NULL;
1337 peer_ctx->mq = NULL;
1338 }
1339 if (NULL != peer_ctx->recv_channel_ctx)
1340 {
1341 /* This is possibly called from within channel destruction */
1342 peer_ctx->recv_channel_ctx->peer_ctx = NULL;
1344 peer_ctx->recv_channel_ctx = NULL;
1345 }
1346
1347 if (GNUNET_YES !=
1349 &peer_ctx->peer_id))
1350 {
1352 "removing peer from peer_ctx->sub->peer_map failed\n");
1353 }
1354 if (peer_ctx->sub == msub)
1355 {
1357 "# known peers",
1359 peer_ctx->sub->peer_map),
1360 GNUNET_NO);
1361 }
1362 GNUNET_free (peer_ctx);
1363 return GNUNET_YES;
1364}
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 1377 of file gnunet-service-rps.c.

1380{
1381 struct Sub *sub = cls;
1382
1383 (void) value;
1384
1386 return GNUNET_YES;
1387}
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 1398 of file gnunet-service-rps.c.

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

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 1443 of file gnunet-service-rps.c.

1446{
1447 const struct GNUNET_DISK_FileHandle *fh = cls;
1448 char peer_string[128];
1449 int size;
1450 ssize_t ret;
1451
1452 (void) value;
1453
1454 if (NULL == peer)
1455 {
1456 return GNUNET_YES;
1457 }
1458 size = GNUNET_snprintf (peer_string,
1459 sizeof(peer_string),
1460 "%s\n",
1461 GNUNET_i2s_full (peer));
1462 GNUNET_assert (53 == size);
1464 peer_string,
1465 size);
1466 GNUNET_assert (size == ret);
1467 return GNUNET_YES;
1468}
static struct GNUNET_DISK_FileHandle * fh
File handle to STDIN, for reading restart/quit commands.
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:686
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 fh, 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 1477 of file gnunet-service-rps.c.

1478{
1479 struct GNUNET_DISK_FileHandle *fh;
1480 uint32_t number_written_peers;
1481 int ret;
1482
1483 if (0 == strncmp ("DISABLE", sub->filename_valid_peers, 7))
1484 {
1485 return;
1486 }
1487
1489 if (GNUNET_SYSERR == ret)
1490 {
1492 "Not able to create directory for file `%s'\n",
1494 GNUNET_break (0);
1495 }
1496 else if (GNUNET_NO == ret)
1497 {
1499 "Directory for file `%s' exists but is not writable for us\n",
1501 GNUNET_break (0);
1502 }
1508 if (NULL == fh)
1509 {
1511 "Not able to write valid peers to file `%s'\n",
1513 return;
1514 }
1516 "Writing %u valid peers to disk\n",
1518 number_written_peers =
1521 fh);
1523 GNUNET_assert (number_written_peers ==
1525}
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:1237
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
@ 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 fh, 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 1538 of file gnunet-service-rps.c.

1539{
1540 struct GNUNET_PeerIdentity *peer;
1541 size_t len;
1542 int ret;
1543
1544 peer = GNUNET_new (struct GNUNET_PeerIdentity);
1545 len = strlen (string_repr);
1546 if (52 > len)
1547 {
1549 "Not able to convert string representation of PeerID to PeerID\n"
1550 "String representation: %s (len %lu) - too short\n",
1551 string_repr,
1552 len);
1553 GNUNET_break (0);
1554 }
1555 else if (52 < len)
1556 {
1557 len = 52;
1558 }
1560 len,
1561 &peer->public_key);
1562 if (GNUNET_OK != ret)
1563 {
1565 "Not able to convert string representation of PeerID to PeerID\n"
1566 "String representation: %s\n",
1567 string_repr);
1568 GNUNET_break (0);
1569 }
1570 return peer;
1571}
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:358
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 1580 of file gnunet-service-rps.c.

1581{
1582 off_t file_size;
1583 uint32_t num_peers;
1584 struct GNUNET_DISK_FileHandle *fh;
1585 char *buf;
1586 ssize_t size_read;
1587 char *iter_buf;
1588 char *str_repr;
1589 const struct GNUNET_PeerIdentity *peer;
1590
1591 if (0 == strncmp ("DISABLE", sub->filename_valid_peers, 7))
1592 {
1593 return;
1594 }
1595
1597 {
1598 return;
1599 }
1603 GNUNET_assert (NULL != fh);
1605 num_peers = file_size / 53;
1606 buf = GNUNET_malloc (file_size);
1607 size_read = GNUNET_DISK_file_read (fh, buf, file_size);
1608 GNUNET_assert (size_read == file_size);
1610 "Restoring %" PRIu32 " peers from file `%s'\n",
1611 num_peers,
1613 for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53)
1614 {
1615 str_repr = GNUNET_strndup (iter_buf, 53);
1616 peer = s2i_full (str_repr);
1617 GNUNET_free (str_repr);
1618 add_valid_peer (peer, sub->valid_peers);
1620 "Restored valid peer %s from disk\n",
1621 GNUNET_i2s_full (peer));
1622 }
1623 iter_buf = NULL;
1624 GNUNET_free (buf);
1626 "num_peers: %" PRIu32 ", _size (sub->valid_peers): %u\n",
1627 num_peers,
1630 {
1632 "Number of restored peers does not match file size. Have probably duplicates.\n");
1633 }
1636 "Restored %u valid peers from disk\n",
1638}
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:482
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:622
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:192
@ 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(), fh, 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 1647 of file gnunet-service-rps.c.

1648{
1649 if (GNUNET_SYSERR ==
1652 sub))
1653 {
1655 "Iteration destroying peers was aborted.\n");
1656 }
1658 sub->peer_map = NULL;
1659 store_valid_peers (sub);
1661 sub->filename_valid_peers = NULL;
1663 sub->valid_peers = NULL;
1664}
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 1678 of file gnunet-service-rps.c.

1681{
1682 struct PeersIteratorCls *it_cls = cls;
1683
1684 (void) value;
1685
1686 return it_cls->iterator (it_cls->cls, peer);
1687}
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 1700 of file gnunet-service-rps.c.

1703{
1704 struct PeersIteratorCls *cls;
1705 int ret;
1706
1707 cls = GNUNET_new (struct PeersIteratorCls);
1708 cls->iterator = iterator;
1709 cls->cls = it_cls;
1712 cls);
1713 GNUNET_free (cls);
1714 return ret;
1715}
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 1731 of file gnunet-service-rps.c.

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

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 1755 of file gnunet-service-rps.c.

1758{
1759 struct PeerContext *peer_ctx;
1760
1761 if (GNUNET_NO == check_peer_known (peer_map, peer))
1762 {
1763 return GNUNET_SYSERR;
1764 }
1765 peer_ctx = get_peer_ctx (peer_map, peer);
1766 return check_peer_flag_set (peer_ctx, flags);
1767}
#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 1781 of file gnunet-service-rps.c.

1783{
1784 struct PeerContext *peer_ctx;
1785
1786 (void) insert_peer (sub, peer); // TODO even needed?
1787 peer_ctx = get_peer_ctx (sub->peer_map, peer);
1788 if ((GNUNET_NO == check_peer_flag (sub->peer_map, peer, Peers_ONLINE)) &&
1789 (NULL == peer_ctx->online_check_pending))
1790 {
1791 check_peer_online (peer_ctx);
1792 return GNUNET_YES;
1793 }
1794 return GNUNET_NO;
1795}
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 1812 of file gnunet-service-rps.c.

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

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 1843 of file gnunet-service-rps.c.

1845{
1846 return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer);
1847}

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 1858 of file gnunet-service-rps.c.

1859{
1861 &peer_ctx->peer_id));
1862 (void) get_channel (peer_ctx);
1863}

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 1876 of file gnunet-service-rps.c.

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

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 1897 of file gnunet-service-rps.c.

1900{
1901 struct PeerContext *peer_ctx;
1902 struct ChannelCtx *channel_ctx;
1903 struct Sub *sub = cls;
1904
1906 "New channel was established to us (Peer %s).\n",
1907 GNUNET_i2s (initiator));
1908 GNUNET_assert (NULL != channel); /* according to cadet API */
1909 /* Make sure we 'know' about this peer */
1910 peer_ctx = create_or_get_peer_ctx (sub, initiator);
1911 set_peer_online (peer_ctx);
1912 (void) add_valid_peer (&peer_ctx->peer_id, peer_ctx->sub->valid_peers);
1913 channel_ctx = add_channel_ctx (peer_ctx);
1914 channel_ctx->channel = channel;
1915 /* We only accept one incoming channel per peer */
1917 initiator)))
1918 {
1920 "Already got one receive channel. Destroying old one.\n");
1921 GNUNET_break_op (0);
1923 peer_ctx->recv_channel_ctx = channel_ctx;
1924 /* return the channel context */
1925 return channel_ctx;
1926 }
1927 peer_ctx->recv_channel_ctx = channel_ctx;
1928 return channel_ctx;
1929}
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 1941 of file gnunet-service-rps.c.

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

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 1965 of file gnunet-service-rps.c.

1966{
1967 if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
1968 &peer_ctx->peer_id))
1969 {
1970 return GNUNET_NO;
1971 }
1972 if (NULL != peer_ctx->send_channel_ctx)
1973 {
1975 (void) check_connected (peer_ctx);
1976 return GNUNET_YES;
1977 }
1978 return GNUNET_NO;
1979}
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 1993 of file gnunet-service-rps.c.

1996{
1997 struct PendingMessage *pending_msg;
1998 struct GNUNET_MQ_Handle *mq;
1999
2001 "Sending message to %s of type %s\n",
2002 GNUNET_i2s (&peer_ctx->peer_id),
2003 type);
2004 pending_msg = insert_pending_message (peer_ctx, ev, type);
2005 mq = get_mq (peer_ctx);
2008 pending_msg);
2009 GNUNET_MQ_send (mq, ev);
2010}
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_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 2026 of file gnunet-service-rps.c.

2029{
2030 struct PeerPendingOp pending_op;
2031
2033 &peer_ctx->peer_id));
2034
2035 // TODO if ONLINE execute immediately
2036
2037 if (GNUNET_NO == check_operation_scheduled (peer_ctx, peer_op))
2038 {
2039 pending_op.op = peer_op;
2040 pending_op.op_cls = cls;
2042 peer_ctx->num_pending_ops,
2043 pending_op);
2044 return GNUNET_YES;
2045 }
2046 return GNUNET_NO;
2047}
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 2146 of file gnunet-service-rps.c.

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

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 2168 of file gnunet-service-rps.c.

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

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 2596 of file gnunet-service-rps.c.

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

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 2224 of file gnunet-service-rps.c.

2226{
2227 struct PeerContext *peer_ctx;
2228 int online;
2229 int ret;
2230
2231 online = check_peer_flag (sub->peer_map, peer, Peers_ONLINE);
2232 peer_ctx = get_peer_ctx (sub->peer_map, peer); // TODO indirection needed?
2233 if ((GNUNET_NO == online) ||
2234 (GNUNET_SYSERR == online)) /* peer is not even known */
2235 {
2236 (void) issue_peer_online_check (sub, peer);
2237 (void) schedule_operation (peer_ctx, insert_in_view_op, sub);
2238 return GNUNET_NO;
2239 }
2240 /* Open channel towards peer to keep connection open */
2241 indicate_sending_intention (peer_ctx);
2242 ret = View_put (sub->view, peer);
2243 if (peer_ctx->sub == msub)
2244 {
2246 "view size",
2247 View_size (peer_ctx->sub->view),
2248 GNUNET_NO);
2249 }
2250 return ret;
2251}
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 2262 of file gnunet-service-rps.c.

2265{
2266 struct GNUNET_MQ_Envelope *ev;
2267 struct GNUNET_RPS_CS_DEBUG_ViewReply *out_msg;
2268 struct Sub *sub;
2269
2270 if (NULL == view_array)
2271 {
2272 if (NULL == cli_ctx->sub)
2273 sub = msub;
2274 else
2275 sub = cli_ctx->sub;
2276 view_size = View_size (sub->view);
2277 view_array = View_get_as_array (sub->view);
2278 }
2279
2280 ev = GNUNET_MQ_msg_extra (out_msg,
2281 view_size * sizeof(struct GNUNET_PeerIdentity),
2283 out_msg->num_peers = htonl (view_size);
2284
2285 GNUNET_memcpy (&out_msg[1],
2286 view_array,
2287 view_size * sizeof(struct GNUNET_PeerIdentity));
2288 GNUNET_MQ_send (cli_ctx->mq, ev);
2289}
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MESSAGE_TYPE_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 2302 of file gnunet-service-rps.c.

2305{
2306 struct GNUNET_MQ_Envelope *ev;
2307 struct GNUNET_RPS_CS_DEBUG_StreamReply *out_msg;
2308
2309 GNUNET_assert (NULL != peers);
2310
2311 ev = GNUNET_MQ_msg_extra (out_msg,
2312 num_peers * sizeof(struct GNUNET_PeerIdentity),
2314 out_msg->num_peers = htonl (num_peers);
2315
2316 GNUNET_memcpy (&out_msg[1],
2317 peers,
2318 num_peers * sizeof(struct GNUNET_PeerIdentity));
2319 GNUNET_MQ_send (cli_ctx->mq, ev);
2320}
#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 2329 of file gnunet-service-rps.c.

2330{
2331 struct ClientContext *cli_ctx_iter;
2332 uint64_t num_peers;
2333 const struct GNUNET_PeerIdentity *view_array;
2334
2335 num_peers = View_size (sub->view);
2336 view_array = View_get_as_array (sub->view);
2337 /* check size of view is small enough */
2339 {
2341 "View is too big to send\n");
2342 return;
2343 }
2344
2345 for (cli_ctx_iter = cli_ctx_head;
2346 NULL != cli_ctx_iter;
2347 cli_ctx_iter = cli_ctx_iter->next)
2348 {
2349 if (1 < cli_ctx_iter->view_updates_left)
2350 {
2351 /* Client wants to receive limited amount of updates */
2352 cli_ctx_iter->view_updates_left -= 1;
2353 }
2354 else if (1 == cli_ctx_iter->view_updates_left)
2355 {
2356 /* Last update of view for client */
2357 cli_ctx_iter->view_updates_left = -1;
2358 }
2359 else if (0 > cli_ctx_iter->view_updates_left)
2360 {
2361 /* Client is not interested in updates */
2362 continue;
2363 }
2364 /* else _updates_left == 0 - infinite amount of updates */
2365
2366 /* send view */
2367 send_view (cli_ctx_iter, view_array, num_peers);
2368 }
2369}
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 2379 of file gnunet-service-rps.c.

2383{
2384 struct ClientContext *cli_ctx_iter;
2385
2387 "Got peer (%s) from biased stream - update all clients\n",
2388 GNUNET_i2s (peers));
2389
2390 for (cli_ctx_iter = cli_ctx_head;
2391 NULL != cli_ctx_iter;
2392 cli_ctx_iter = cli_ctx_iter->next)
2393 {
2394 if ((GNUNET_YES == cli_ctx_iter->stream_update) &&
2395 ((sub == cli_ctx_iter->sub) || (sub == msub) ))
2396 {
2397 send_stream_peers (cli_ctx_iter, num_peers, peers);
2398 }
2399 }
2400}
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 2411 of file gnunet-service-rps.c.

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

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 2452 of file gnunet-service-rps.c.

2453{
2454 unsigned int sampler_size;
2455
2456 // TODO statistics
2457 // TODO respect the min, max
2458 sampler_size = RPS_sampler_get_size (sampler);
2459 if (sampler_size > new_size * 4)
2460 { /* Shrinking */
2461 RPS_sampler_resize (sampler, sampler_size / 2);
2462 }
2463 else if (sampler_size < new_size)
2464 { /* Growing */
2465 RPS_sampler_resize (sampler, sampler_size * 2);
2466 }
2467 LOG (GNUNET_ERROR_TYPE_DEBUG, "sampler_size is now %u\n", sampler_size);
2468}
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 2521 of file gnunet-service-rps.c.

2524{
2525 uint32_t send_size;
2526 struct GNUNET_MQ_Envelope *ev;
2527 struct GNUNET_RPS_P2P_PullReplyMessage *out_msg;
2528
2529 /* Compute actual size */
2530 send_size = sizeof(struct GNUNET_RPS_P2P_PullReplyMessage)
2531 + num_peer_ids * sizeof(struct GNUNET_PeerIdentity);
2532
2534 /* Compute number of peers to send
2535 * If too long, simply truncate */
2536 // TODO select random ones via permutation
2537 // or even better: do good protocol design
2538 send_size =
2540 - sizeof(struct GNUNET_RPS_P2P_PullReplyMessage))
2541 / sizeof(struct GNUNET_PeerIdentity);
2542 else
2543 send_size = num_peer_ids;
2544
2546 "Going to send PULL REPLY with %u peers to %s\n",
2547 send_size, GNUNET_i2s (&peer_ctx->peer_id));
2548
2549 ev = GNUNET_MQ_msg_extra (out_msg,
2550 send_size * sizeof(struct GNUNET_PeerIdentity),
2552 out_msg->num_peers = htonl (send_size);
2553 GNUNET_memcpy (&out_msg[1], peer_ids,
2554 send_size * sizeof(struct GNUNET_PeerIdentity));
2555
2556 send_message (peer_ctx, ev, "PULL REPLY");
2557 if (peer_ctx->sub == msub)
2558 {
2559 GNUNET_STATISTICS_update (stats, "# pull reply send issued", 1, GNUNET_NO);
2560 }
2561 // TODO check with send intention: as send_channel is used/opened we indicate
2562 // a sending intention without intending it.
2563 // -> clean peer afterwards?
2564 // -> use recv_channel?
2565}
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 2577 of file gnunet-service-rps.c.

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

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 2618 of file gnunet-service-rps.c.

2620{
2621 struct Sub *sub = cls;
2622
2624 "Updating samplers with peer %s from insert_in_sampler()\n",
2625 GNUNET_i2s (peer));
2626 RPS_sampler_update (sub->sampler, peer);
2627 if (0 < RPS_sampler_count_id (sub->sampler, peer))
2628 {
2629 /* Make sure we 'know' about this peer */
2630 (void) issue_peer_online_check (sub, peer);
2631 /* Establish a channel towards that peer to indicate we are going to send
2632 * messages to it */
2633 // indicate_sending_intention (peer);
2634 }
2635 if (sub == msub)
2636 {
2638 "# observed peers in gossip",
2639 1,
2640 GNUNET_NO);
2641 }
2642#ifdef TO_FILE
2643 sub->num_observed_peers++;
2646 peer,
2647 NULL,
2649 uint32_t num_observed_unique_peers =
2652 "# unique peers in gossip",
2653 num_observed_unique_peers,
2654 GNUNET_NO);
2655#ifdef TO_FILE_FULL
2656 to_file (sub->file_name_observed_log,
2657 "%" PRIu32 " %" PRIu32 " %f\n",
2658 sub->num_observed_peers,
2659 num_observed_unique_peers,
2660 1.0 * num_observed_unique_peers / sub->num_observed_peers)
2661#endif /* TO_FILE_FULL */
2662#endif /* TO_FILE */
2663}
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 2677 of file gnunet-service-rps.c.

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

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 2706 of file gnunet-service-rps.c.

2707{
2708 /* struct GNUNET_CADET_Channel *channel; */
2709 if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
2710 &peer_ctx->peer_id))
2711 {
2712 return GNUNET_NO;
2713 }
2714 if (GNUNET_YES == check_sending_channel_exists (peer_ctx))
2715 {
2716 if ((0 < RPS_sampler_count_id (peer_ctx->sub->sampler,
2717 &peer_ctx->peer_id)) ||
2718 (GNUNET_YES == View_contains_peer (peer_ctx->sub->view,
2719 &peer_ctx->peer_id)) ||
2721 &peer_ctx->peer_id)) ||
2723 &peer_ctx->peer_id)) ||
2724 (GNUNET_YES == check_peer_flag (peer_ctx->sub->peer_map,
2725 &peer_ctx->peer_id,
2727 { /* If we want to keep the connection to peer open */
2728 return GNUNET_YES;
2729 }
2730 return GNUNET_NO;
2731 }
2732 return GNUNET_NO;
2733}
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 2744 of file gnunet-service-rps.c.

2746{
2747 (void) View_remove_peer (sub->view,
2748 peer);
2750 peer);
2752 peer);
2754 peer);
2755 /* We want to destroy the peer now.
2756 * Sometimes, it just seems that it's already been removed from the peer_map,
2757 * so check the peer_map first. */
2759 peer))
2760 {
2762 peer));
2763 }
2764}
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 2776 of file gnunet-service-rps.c.

2778{
2780 peer)))
2781 {
2783 "Going to remove send channel to peer %s\n",
2784 GNUNET_i2s (peer));
2785 #if ENABLE_MALICIOUS
2786 if (0 != GNUNET_memcmp (&attacked_peer,
2787 peer))
2789 peer));
2790 #else /* ENABLE_MALICIOUS */
2792 peer));
2793 #endif /* ENABLE_MALICIOUS */
2794 }
2795
2797 peer))
2798 {
2799 /* Peer was already removed by callback on destroyed channel */
2801 "Peer was removed from our knowledge during cleanup\n");
2802 return;
2803 }
2804
2806 peer))) &&
2807 (GNUNET_NO == View_contains_peer (sub->view, peer)) &&
2810 (0 == RPS_sampler_count_id (sub->sampler, peer)) &&
2811 (GNUNET_YES == check_removable (get_peer_ctx (sub->peer_map, peer))))
2812 { /* We can safely remove this peer */
2814 "Going to remove peer %s\n",
2815 GNUNET_i2s (peer));
2816 remove_peer (sub, peer);
2817 return;
2818 }
2819}
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 2880 of file gnunet-service-rps.c.

2883{
2884 struct Sub *sub;
2885
2886 sub = GNUNET_new (struct Sub);
2887
2888 /* With the hash generated from the secret value this service only connects
2889 * to rps instances that share the value */
2890 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
2891 GNUNET_MQ_hd_fixed_size (peer_check,
2893 struct GNUNET_MessageHeader,
2894 NULL),
2895 GNUNET_MQ_hd_fixed_size (peer_push,
2897 struct GNUNET_MessageHeader,
2898 NULL),
2899 GNUNET_MQ_hd_fixed_size (peer_pull_request,
2901 struct GNUNET_MessageHeader,
2902 NULL),
2903 GNUNET_MQ_hd_var_size (peer_pull_reply,
2906 NULL),
2908 };
2909 sub->hash = *hash;
2910 sub->cadet_port =
2912 &sub->hash,
2913 &handle_inbound_channel, /* Connect handler */
2914 sub, /* cls */
2915 NULL, /* WindowSize handler */
2916 &cleanup_destroyed_channel, /* Disconnect handler */
2917 cadet_handlers);
2918 if (NULL == sub->cadet_port)
2919 {
2921 "Cadet port `%s' is already in use.\n",
2923 GNUNET_assert (0);
2924 }
2925
2926 /* Set up general data structure to keep track about peers */
2928 if (GNUNET_OK !=
2930 "rps",
2931 "FILENAME_VALID_PEERS",
2932 &sub->filename_valid_peers))
2933 {
2935 "rps",
2936 "FILENAME_VALID_PEERS");
2937 }
2938 if (0 != strncmp ("DISABLE", sub->filename_valid_peers, 7))
2939 {
2940 char *tmp_filename_valid_peers;
2941 char str_hash[105];
2942
2943 GNUNET_snprintf (str_hash,
2944 sizeof(str_hash), "%s",
2945 GNUNET_h2s_full (hash));
2946 tmp_filename_valid_peers = sub->filename_valid_peers;
2948 "%s%s",
2949 tmp_filename_valid_peers,
2950 str_hash);
2951 GNUNET_free (tmp_filename_valid_peers);
2952 }
2954
2955 /* Set up the sampler */
2956 sub->sampler_size_est_min = sampler_size;
2957 sub->sampler_size_est_need = sampler_size;;
2958 LOG (GNUNET_ERROR_TYPE_DEBUG, "MINSIZE is %u\n", sub->sampler_size_est_min);
2959 GNUNET_assert (0 != round_interval.rel_value_us);
2960 sub->round_interval = round_interval;
2961 sub->sampler = RPS_sampler_init (sampler_size,
2962 round_interval);
2963
2964 /* Logging of internals */
2965#ifdef TO_FILE_FULL
2966 // FIXME: The service cannot know the index, which is required by this
2967 // function:
2968 // sub->file_name_view_log = store_prefix_file_name (&own_identity, "view");
2969#endif /* TO_FILE_FULL */
2970#ifdef TO_FILE
2971#ifdef TO_FILE_FULL
2972 // FIXME: The service cannot know the index, which is required by this
2973 // function:
2974 // sub->file_name_observed_log = store_prefix_file_name (&own_identity,
2975 // "observed");
2976#endif /* TO_FILE_FULL */
2977 sub->num_observed_peers = 0;
2979 GNUNET_NO);
2980#endif /* TO_FILE */
2981
2982 /* Set up data structures for gossip */
2983 sub->push_map = CustomPeerMap_create (4);
2984 sub->pull_map = CustomPeerMap_create (4);
2985 sub->view_size_est_min = sampler_size;;
2986 sub->view = View_create (sub->view_size_est_min);
2987 if (sub == msub)
2988 {
2990 "view size aim",
2991 sub->view_size_est_min,
2992 GNUNET_NO);
2993 }
2994
2995 /* Start executing rounds */
2997
2998 return sub;
2999}
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:954
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 3058 of file gnunet-service-rps.c.

3059{
3060 GNUNET_assert (NULL != sub);
3061 GNUNET_assert (NULL != sub->do_round_task);
3063 sub->do_round_task = NULL;
3064
3065 /* Disconnect from cadet */
3067 sub->cadet_port = NULL;
3068
3069 /* Clean up data structures for peers */
3071 sub->sampler = NULL;
3072 View_destroy (sub->view);
3073 sub->view = NULL;
3075 sub->push_map = NULL;
3077 sub->pull_map = NULL;
3078 peers_terminate (sub);
3079
3080 /* Free leftover data structures */
3081#ifdef TO_FILE_FULL
3082 GNUNET_free (sub->file_name_view_log);
3083 sub->file_name_view_log = NULL;
3084#endif /* TO_FILE_FULL */
3085#ifdef TO_FILE
3086#ifdef TO_FILE_FULL
3087 GNUNET_free (sub->file_name_observed_log);
3088 sub->file_name_observed_log = NULL;
3089#endif /* TO_FILE_FULL */
3090
3091 // FIXME: Currently this calls malfunctionning code
3092 // /* Write push frequencies to disk */
3093 // write_histogram_to_file (sub->push_recv,
3094 // "push_recv");
3095
3096 // /* Write push deltas to disk */
3097 // write_histogram_to_file (sub->push_delta,
3098 // "push_delta");
3099
3100 // /* Write pull delays to disk */
3101 // write_histogram_to_file (sub->pull_delays,
3102 // "pull_delays");
3103
3105 sub->observed_unique_peers = NULL;
3106#endif /* TO_FILE */
3107
3108 GNUNET_free (sub);
3109}
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:801

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 3128 of file gnunet-service-rps.c.

3130{
3131 (void) cls;
3132 (void) my_identity;
3133
3135}
struct GNUNET_PeerIdentity my_identity
Our peer identity.

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 
)

Callback for core.

Method called whenever a given peer connects.

Parameters
clsclosure - unused
peerpeer identity this notification is about
Returns
closure given to core_disconnects as peer_cls

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

3150{
3151 (void) cls;
3152 (void) mq;
3153
3156 peer,
3157 NULL,
3159 return NULL;
3160}

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 3172 of file gnunet-service-rps.c.

3175{
3176 (void) cls;
3177 (void) peer_cls;
3178
3180}

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 3194 of file gnunet-service-rps.c.

3195{
3196 GNUNET_assert (NULL != cli_ctx);
3199 cli_ctx);
3200 if (NULL != cli_ctx->sub)
3201 {
3202 destroy_sub (cli_ctx->sub);
3203 cli_ctx->sub = NULL;
3204 }
3205 GNUNET_free (cli_ctx);
3206}
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 3217 of file gnunet-service-rps.c.

3218{
3219 double estimate;
3220
3221 // double scale; // TODO this might go global/config
3222
3224 "Received a ns estimate - logest: %f, std_dev: %f (old_size: %u)\n",
3225 logestimate, std_dev, RPS_sampler_get_size (sub->sampler));
3226 // scale = .01;
3227 estimate = GNUNET_NSE_log_estimate_to_n (logestimate);
3228 // GNUNET_NSE_log_estimate_to_n (logestimate);
3229 estimate = pow (estimate, 1.0 / 3);
3230 // TODO add if std_dev is a number
3231 // estimate += (std_dev * scale);
3232 if (sub->view_size_est_min < ceil (estimate))
3233 {
3234 LOG (GNUNET_ERROR_TYPE_DEBUG, "Changing estimate to %f\n", estimate);
3235 sub->sampler_size_est_need = estimate;
3236 sub->view_size_est_need = estimate;
3237 }
3238 else
3239 {
3240 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not using estimate %f\n", estimate);
3241 // sub->sampler_size_est_need = sub->view_size_est_min;
3243 }
3244 if (sub == msub)
3245 {
3247 "view size aim",
3248 sub->view_size_est_need,
3249 GNUNET_NO);
3250 }
3251
3252 /* If the NSE has changed adapt the lists accordingly */
3255}
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 3272 of file gnunet-service-rps.c.

3275{
3276 (void) cls;
3277 (void) timestamp;
3278 struct ClientContext *cli_ctx_iter;
3279
3280 adapt_sizes (msub, logestimate, std_dev);
3281 for (cli_ctx_iter = cli_ctx_head;
3282 NULL != cli_ctx_iter;
3283 cli_ctx_iter = cli_ctx_iter->next)
3284 {
3285 if (NULL != cli_ctx_iter->sub)
3286 {
3287 adapt_sizes (cli_ctx_iter->sub, logestimate, std_dev);
3288 }
3289 }
3290}
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, and ClientContext::sub.

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 3303 of file gnunet-service-rps.c.

3304{
3305 struct ClientContext *cli_ctx = cls;
3306 uint16_t msize = ntohs (msg->header.size);
3307 uint32_t num_peers = ntohl (msg->num_peers);
3308
3309 msize -= sizeof(struct GNUNET_RPS_CS_SeedMessage);
3310 if ((msize / sizeof(struct GNUNET_PeerIdentity) != num_peers) ||
3311 (msize % sizeof(struct GNUNET_PeerIdentity) != 0))
3312 {
3314 "message says it sends %" PRIu32 " peers, have space for %lu peers\n",
3315 ntohl (msg->num_peers),
3316 (msize / sizeof(struct GNUNET_PeerIdentity)));
3317 GNUNET_break (0);
3319 return GNUNET_SYSERR;
3320 }
3321 return GNUNET_OK;
3322}
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2489
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 3332 of file gnunet-service-rps.c.

3334{
3335 struct ClientContext *cli_ctx = cls;
3336 struct GNUNET_PeerIdentity *peers;
3337 uint32_t num_peers;
3338 uint32_t i;
3339
3340 num_peers = ntohl (msg->num_peers);
3341 peers = (struct GNUNET_PeerIdentity *) &msg[1];
3342
3344 "Client seeded peers:\n");
3346
3347 for (i = 0; i < num_peers; i++)
3348 {
3350 "Updating samplers with seed %" PRIu32 ": %s\n",
3351 i,
3352 GNUNET_i2s (&peers[i]));
3353
3354 if (NULL != msub)
3355 got_peer (msub, &peers[i]); /* Condition needed? */
3356 if (NULL != cli_ctx->sub)
3357 got_peer (cli_ctx->sub, &peers[i]);
3358 }
3360}
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:2408

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 3371 of file gnunet-service-rps.c.

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

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 3397 of file gnunet-service-rps.c.

3399{
3400 struct ClientContext *cli_ctx = cls;
3401
3402 (void) msg;
3403
3405 "Client does not want to receive updates of view any more.\n");
3406
3407 GNUNET_assert (NULL != cli_ctx);
3408 cli_ctx->view_updates_left = 0;
3410 if (GNUNET_YES == cli_ctx->stream_update)
3411 {
3412 destroy_cli_ctx (cli_ctx);
3413 }
3414}
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 3424 of file gnunet-service-rps.c.

3427{
3428 struct ClientContext *cli_ctx = cls;
3429
3430 (void) msg;
3431
3433 "Client requested peers from biased stream.\n");
3434 cli_ctx->stream_update = GNUNET_YES;
3435
3436 GNUNET_assert (NULL != cli_ctx);
3438}

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 3448 of file gnunet-service-rps.c.

3450{
3451 struct ClientContext *cli_ctx = cls;
3452
3453 (void) msg;
3454
3456 "Client canceled receiving peers from biased stream.\n");
3457 cli_ctx->stream_update = GNUNET_NO;
3458
3459 GNUNET_assert (NULL != cli_ctx);
3461}

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 3471 of file gnunet-service-rps.c.

3473{
3474 struct ClientContext *cli_ctx = cls;
3475
3476 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client requested start of a new sub.\n");
3477 if ((NULL != cli_ctx->sub) &&
3478 (0 != memcmp (&cli_ctx->sub->hash,
3479 &msg->hash,
3480 sizeof(struct GNUNET_HashCode))) )
3481 {
3483 "Already have a Sub with different share for this client. Remove old one, add new.\n");
3484 destroy_sub (cli_ctx->sub);
3485 cli_ctx->sub = NULL;
3486 }
3487 cli_ctx->sub = new_sub (&msg->hash,
3488 msub->sampler_size_est_min, // TODO make api input?
3489 GNUNET_TIME_relative_ntoh (msg->round_interval));
3491}
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:628
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 3501 of file gnunet-service-rps.c.

3503{
3504 struct ClientContext *cli_ctx = cls;
3505
3506 GNUNET_assert (NULL != cli_ctx->sub);
3507 if (0 != memcmp (&cli_ctx->sub->hash, &msg->hash, sizeof(struct
3509 {
3511 "Share of current sub and request differ!\n");
3512 }
3513 destroy_sub (cli_ctx->sub);
3514 cli_ctx->sub = NULL;
3516}

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 3870 of file gnunet-service-rps.c.

3872{
3873 struct GNUNET_TIME_Relative half_interval;
3875 unsigned int rand_delay;
3876 unsigned int max_rand_delay;
3877
3878 if (0 == spread)
3879 {
3881 "Not accepting spread of 0\n");
3882 GNUNET_break (0);
3883 GNUNET_assert (0);
3884 }
3885 GNUNET_assert (0 != mean.rel_value_us);
3886
3887 /* Compute random time value between spread * mean and spread * mean */
3888 half_interval = GNUNET_TIME_relative_divide (mean, spread);
3889
3890 max_rand_delay = GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us
3891 / mean.rel_value_us * (2 / spread);
3897 max_rand_delay);
3898 ret = GNUNET_TIME_relative_saturating_multiply (mean, rand_delay);