GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
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_peerinfo_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 <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_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
 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 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_PEERINFO_Handlepeerinfo_handle
 Handler to PEERINFO. More...
 
static struct GNUNET_PEERINFO_NotifyContextpeerinfo_notify_handle
 Handle for cancellation of iteration over peers. 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 44 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 63 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 68 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 74 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 79 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 85 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 288 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 296 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 4283 of file gnunet-service-rps.c.

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

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(), 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, peer, 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 GNUNET_STRINGS_relative_time_to_string(), 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 615 of file gnunet-service-rps.c.

617 {
618  struct PeerContext *ctx;
619  int ret;
620 
624  GNUNET_assert (NULL != ctx);
625  return ctx;
626 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_CONTAINER_MultiPeerMap * peer_map
Peermap to get the index of a given peer ID quick.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
@ GNUNET_YES
Definition: gnunet_common.h:97
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.
int 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).
#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, peer, peer_map, and ret.

Referenced by check_connected(), check_peer_flag(), clean_peer(), compute_rand_delay(), create_or_get_peer_ctx(), do_round(), got_peer(), handle_inbound_channel(), 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 641 of file gnunet-service-rps.c.

643 {
644  if (NULL != peer_map)
645  {
647  }
648  else
649  {
650  return GNUNET_NO;
651  }
652 }

References GNUNET_CONTAINER_multipeermap_contains(), GNUNET_NO, peer, and peer_map.

Referenced by check_connected(), check_peer_flag(), check_sending_channel_exists(), check_sending_channel_needed(), compute_rand_delay(), create_or_get_peer_ctx(), create_peer_ctx(), destroy_sending_channel(), 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 664 of file gnunet-service-rps.c.

666 {
667  struct PeerContext *ctx;
668  int ret;
669 
671 
672  ctx = GNUNET_new (struct PeerContext);
673  ctx->peer_id = *peer;
674  ctx->sub = sub;
678  if (sub == msub)
679  {
681  "# known peers",
683  GNUNET_NO);
684  }
685  return ctx;
686 }
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, peer, 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 698 of file gnunet-service-rps.c.

700 {
701  if (GNUNET_NO == check_peer_known (sub->peer_map, peer))
702  {
703  return create_peer_ctx (sub, peer);
704  }
705  return get_peer_ctx (sub->peer_map, peer);
706 }
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, peer, 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 720 of file gnunet-service-rps.c.

721 {
722  /* If we don't know about this peer we don't know whether it's online */
723  if (GNUNET_NO == check_peer_known (peer_ctx->sub->peer_map,
724  &peer_ctx->peer_id))
725  {
726  return GNUNET_NO;
727  }
728  /* Get the context */
729  peer_ctx = get_peer_ctx (peer_ctx->sub->peer_map, &peer_ctx->peer_id);
730  /* If we have no channel to this peer we don't know whether it's online */
731  if ((NULL == peer_ctx->send_channel_ctx) &&
732  (NULL == peer_ctx->recv_channel_ctx))
733  {
734  UNSET_PEER_FLAG (peer_ctx, Peers_ONLINE);
735  return GNUNET_NO;
736  }
737  /* Otherwise (if we have a channel, we know that it's online */
738  SET_PEER_FLAG (peer_ctx, Peers_ONLINE);
739  return GNUNET_YES;
740 }
#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 778 of file gnunet-service-rps.c.

781 {
782  struct GetRandPeerIteratorCls *iterator_cls = cls;
783 
784  (void) value;
785 
786  if (0 >= iterator_cls->index)
787  {
788  iterator_cls->peer = peer;
789  return GNUNET_NO;
790  }
791  iterator_cls->index--;
792  return GNUNET_YES;
793 }
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, 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 805 of file gnunet-service-rps.c.

806 {
807  struct GetRandPeerIteratorCls *iterator_cls;
808  const struct GNUNET_PeerIdentity *ret;
809 
810  iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls);
813  valid_peers));
814  (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
816  iterator_cls);
817  ret = iterator_cls->peer;
818  GNUNET_free (iterator_cls);
819  return ret;
820 }
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 835 of file gnunet-service-rps.c.

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

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

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

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

3529 {
3530  const struct ChannelCtx *channel_ctx = cls;
3531  const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3532 
3533  (void) msg;
3534 
3536  "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer));
3537  if (channel_ctx->peer_ctx->sub == msub)
3538  {
3540  "# pending online checks",
3541  -1,
3542  GNUNET_NO);
3543  }
3544 
3545  GNUNET_CADET_receive_done (channel_ctx->channel);
3546 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888

References ChannelCtx::channel, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_NO, GNUNET_STATISTICS_update(), LOG, msg, msub, peer, 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 3559 of file gnunet-service-rps.c.

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

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

3700 {
3701  struct ChannelCtx *channel_ctx = cls;
3702  struct PeerContext *sender_ctx = channel_ctx->peer_ctx;
3703 
3704  if (sizeof(struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->header.size))
3705  {
3706  GNUNET_break_op (0);
3707  return GNUNET_SYSERR;
3708  }
3709 
3710  if ((ntohs (msg->header.size) - sizeof(struct
3712  / sizeof(struct GNUNET_PeerIdentity) != ntohl (msg->num_peers))
3713  {
3715  "message says it sends %" PRIu32 " peers, have space for %lu peers\n",
3716  ntohl (msg->num_peers),
3717  (ntohs (msg->header.size) - sizeof(struct
3719  / sizeof(struct GNUNET_PeerIdentity));
3720  GNUNET_break_op (0);
3721  return GNUNET_SYSERR;
3722  }
3723 
3724  if (GNUNET_YES != check_peer_flag (sender_ctx->sub->peer_map,
3725  &sender_ctx->peer_id,
3727  {
3729  "Received a pull reply from a peer (%s) we didn't request one from!\n",
3730  GNUNET_i2s (&sender_ctx->peer_id));
3731  if (sender_ctx->sub == msub)
3732  {
3734  "# unrequested pull replies",
3735  1,
3736  GNUNET_NO);
3737  }
3738  }
3739  return GNUNET_OK;
3740 }
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
@ 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 3750 of file gnunet-service-rps.c.

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

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

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

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

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

992 {
993  /* There exists a copy-paste-clone in run() */
994  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
995  GNUNET_MQ_hd_fixed_size (peer_check,
997  struct GNUNET_MessageHeader,
998  NULL),
999  GNUNET_MQ_hd_fixed_size (peer_push,
1001  struct GNUNET_MessageHeader,
1002  NULL),
1003  GNUNET_MQ_hd_fixed_size (peer_pull_request,
1005  struct GNUNET_MessageHeader,
1006  NULL),
1007  GNUNET_MQ_hd_var_size (peer_pull_reply,
1010  NULL),
1012  };
1013 
1014 
1015  if (NULL == peer_ctx->send_channel_ctx)
1016  {
1018  "Trying to establish channel to peer %s\n",
1019  GNUNET_i2s (&peer_ctx->peer_id));
1020  peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx);
1021  peer_ctx->send_channel_ctx->channel =
1023  peer_ctx->send_channel_ctx, /* context */
1024  &peer_ctx->peer_id,
1025  &peer_ctx->sub->hash,
1026  NULL, /* WindowSize handler */
1027  &cleanup_destroyed_channel, /* Disconnect handler */
1028  cadet_handlers);
1029  }
1030  GNUNET_assert (NULL != peer_ctx->send_channel_ctx);
1031  GNUNET_assert (NULL != peer_ctx->send_channel_ctx->channel);
1032  return peer_ctx->send_channel_ctx->channel;
1033 }
struct GNUNET_CADET_Handle * cadet_handle
Handler to CADET.
static void cleanup_destroyed_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
This is called when a channel is destroyed.
static struct ChannelCtx * add_channel_ctx(struct PeerContext *peer_ctx)
Allocate memory for a new channel context and insert it into DLL.
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:1031
#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 1046 of file gnunet-service-rps.c.

1047 {
1048  if (NULL == peer_ctx->mq)
1049  {
1050  peer_ctx->mq = GNUNET_CADET_get_mq (get_channel (peer_ctx));
1051  }
1052  return peer_ctx->mq;
1053 }
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 peer.
Definition: cadet_api.c:1082

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

1068 {
1069  struct PendingMessage *pending_msg;
1070 
1071  pending_msg = GNUNET_new (struct PendingMessage);
1072  pending_msg->ev = ev;
1073  pending_msg->peer_ctx = peer_ctx;
1074  pending_msg->type = type;
1077  pending_msg);
1078  return pending_msg;
1079 }
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.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References PendingMessage::ev, GNUNET_CONTAINER_DLL_insert, GNUNET_new, PendingMessage::peer_ctx, PeerContext::pending_messages_head, PeerContext::pending_messages_tail, PendingMessage::type, and 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 1116 of file gnunet-service-rps.c.

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

1140 {
1142  "Get informed about peer %s getting online\n",
1143  GNUNET_i2s (&peer_ctx->peer_id));
1144 
1145  struct GNUNET_MQ_Handle *mq;
1146  struct GNUNET_MQ_Envelope *ev;
1147 
1149  peer_ctx->online_check_pending =
1150  insert_pending_message (peer_ctx, ev, "Check online");
1151  mq = get_mq (peer_ctx);
1154  peer_ctx);
1155  GNUNET_MQ_send (mq, ev);
1156  if (peer_ctx->sub == msub)
1157  {
1159  "# pending online checks",
1160  1,
1161  GNUNET_NO);
1162  }
1163 }
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 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.
static struct GNUNET_MQ_Handle * get_mq(struct PeerContext *peer_ctx)
Get the message queue (GNUNET_MQ_Handle) of a specific peer.
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:355
#define GNUNET_MQ_msg_header(type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header.
Definition: gnunet_mq_lib.h:76
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:787
Handle to a message queue.
Definition: mq.c:86

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

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

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
clsContext of the channel

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

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

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

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

1243 {
1244  GNUNET_assert (NULL ==
1245  channel_ctx->destruction_task);
1246  GNUNET_assert (NULL !=
1247  channel_ctx->channel);
1248  channel_ctx->destruction_task =
1250  channel_ctx);
1251 }
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:1296

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

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

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

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

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

1444 {
1445  const struct GNUNET_DISK_FileHandle *fh = cls;
1446  char peer_string[128];
1447  int size;
1448  ssize_t ret;
1449 
1450  (void) value;
1451 
1452  if (NULL == peer)
1453  {
1454  return GNUNET_YES;
1455  }
1456  size = GNUNET_snprintf (peer_string,
1457  sizeof(peer_string),
1458  "%s\n",
1459  GNUNET_i2s_full (peer));
1460  GNUNET_assert (53 == size);
1462  peer_string,
1463  size);
1464  GNUNET_assert (size == ret);
1465  return GNUNET_YES;
1466 }
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:67
Handle used to access files (and pipes).

References fh, GNUNET_assert, GNUNET_DISK_file_write(), GNUNET_i2s_full(), GNUNET_snprintf(), GNUNET_YES, peer, 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 1475 of file gnunet-service-rps.c.

1476 {
1477  struct GNUNET_DISK_FileHandle *fh;
1478  uint32_t number_written_peers;
1479  int ret;
1480 
1481  if (0 == strncmp ("DISABLE", sub->filename_valid_peers, 7))
1482  {
1483  return;
1484  }
1485 
1487  if (GNUNET_SYSERR == ret)
1488  {
1490  "Not able to create directory for file `%s'\n",
1491  sub->filename_valid_peers);
1492  GNUNET_break (0);
1493  }
1494  else if (GNUNET_NO == ret)
1495  {
1497  "Directory for file `%s' exists but is not writable for us\n",
1498  sub->filename_valid_peers);
1499  GNUNET_break (0);
1500  }
1506  if (NULL == fh)
1507  {
1509  "Not able to write valid peers to file `%s'\n",
1510  sub->filename_valid_peers);
1511  return;
1512  }
1514  "Writing %u valid peers to disk\n",
1516  number_written_peers =
1519  fh);
1521  GNUNET_assert (number_written_peers ==
1523 }
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:1235
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1306
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 1536 of file gnunet-service-rps.c.

1537 {
1538  struct GNUNET_PeerIdentity *peer;
1539  size_t len;
1540  int ret;
1541 
1542  peer = GNUNET_new (struct GNUNET_PeerIdentity);
1543  len = strlen (string_repr);
1544  if (52 > len)
1545  {
1547  "Not able to convert string representation of PeerID to PeerID\n"
1548  "String representation: %s (len %lu) - too short\n",
1549  string_repr,
1550  len);
1551  GNUNET_break (0);
1552  }
1553  else if (52 < len)
1554  {
1555  len = 52;
1556  }
1558  len,
1559  &peer->public_key);
1560  if (GNUNET_OK != ret)
1561  {
1563  "Not able to convert string representation of PeerID to PeerID\n"
1564  "String representation: %s\n",
1565  string_repr);
1566  GNUNET_break (0);
1567  }
1568  return peer;
1569 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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:357

References GNUNET_break, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_ERROR_TYPE_WARNING, GNUNET_new, GNUNET_OK, len, LOG, peer, 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 1578 of file gnunet-service-rps.c.

1579 {
1580  off_t file_size;
1581  uint32_t num_peers;
1582  struct GNUNET_DISK_FileHandle *fh;
1583  char *buf;
1584  ssize_t size_read;
1585  char *iter_buf;
1586  char *str_repr;
1587  const struct GNUNET_PeerIdentity *peer;
1588 
1589  if (0 == strncmp ("DISABLE", sub->filename_valid_peers, 7))
1590  {
1591  return;
1592  }
1593 
1595  {
1596  return;
1597  }
1601  GNUNET_assert (NULL != fh);
1603  num_peers = file_size / 53;
1604  buf = GNUNET_malloc (file_size);
1605  size_read = GNUNET_DISK_file_read (fh, buf, file_size);
1606  GNUNET_assert (size_read == file_size);
1608  "Restoring %" PRIu32 " peers from file `%s'\n",
1609  num_peers,
1610  sub->filename_valid_peers);
1611  for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53)
1612  {
1613  str_repr = GNUNET_strndup (iter_buf, 53);
1614  peer = s2i_full (str_repr);
1615  GNUNET_free (str_repr);
1618  "Restored valid peer %s from disk\n",
1619  GNUNET_i2s_full (peer));
1620  }
1621  iter_buf = NULL;
1622  GNUNET_free (buf);
1624  "num_peers: %" PRIu32 ", _size (sub->valid_peers): %u\n",
1625  num_peers,
1628  {
1630  "Number of restored peers does not match file size. Have probably duplicates.\n");
1631  }
1634  "Restored %u valid peers from disk\n",
1636 }
static unsigned int num_peers
static const struct GNUNET_PeerIdentity * s2i_full(const char *string_repr)
Convert string representation of peer id to peer id.
static char buf[2048]
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:193
@ 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(), buf, 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, peer, 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 1645 of file gnunet-service-rps.c.

1646 {
1647  if (GNUNET_SYSERR ==
1650  sub))
1651  {
1653  "Iteration destroying peers was aborted.\n");
1654  }
1656  sub->peer_map = NULL;
1657  store_valid_peers (sub);
1659  sub->filename_valid_peers = NULL;
1661  sub->valid_peers = NULL;
1662 }
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 1676 of file gnunet-service-rps.c.

1679 {
1680  struct PeersIteratorCls *it_cls = cls;
1681 
1682  (void) value;
1683 
1684  return it_cls->iterator (it_cls->cls, peer);
1685 }
Closure to valid_peer_iterator.
PeersIterator iterator
Iterator function.
void * cls
Closure to iterator.

References PeersIteratorCls::cls, PeersIteratorCls::iterator, peer, 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 1698 of file gnunet-service-rps.c.

1701 {
1702  struct PeersIteratorCls *cls;
1703  int ret;
1704 
1705  cls = GNUNET_new (struct PeersIteratorCls);
1706  cls->iterator = iterator;
1707  cls->cls = it_cls;
1710  cls);
1711  GNUNET_free (cls);
1712  return ret;
1713 }
static int valid_peer_iterator(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Iterator over #valid_peers hash map entries.
static int iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.

References PeersIteratorCls::cls, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_free, GNUNET_new, 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 1729 of file gnunet-service-rps.c.

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

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

Referenced by compute_rand_delay(), 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 1753 of file gnunet-service-rps.c.

1756 {
1757  struct PeerContext *peer_ctx;
1758 
1760  {
1761  return GNUNET_SYSERR;
1762  }
1763  peer_ctx = get_peer_ctx (peer_map, peer);
1764  return check_peer_flag_set (peer_ctx, flags);
1765 }
#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, GNUNET_SYSERR, peer, and peer_map.

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

1781 {
1782  struct PeerContext *peer_ctx;
1783 
1784  (void) insert_peer (sub, peer); // TODO even needed?
1785  peer_ctx = get_peer_ctx (sub->peer_map, peer);
1787  (NULL == peer_ctx->online_check_pending))
1788  {
1789  check_peer_online (peer_ctx);
1790  return GNUNET_YES;
1791  }
1792  return GNUNET_NO;
1793 }
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, peer, Sub::peer_map, Peers_ONLINE, and PeerContext::sub.

Referenced by compute_rand_delay(), got_peer(), 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 1810 of file gnunet-service-rps.c.

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

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

1843 {
1844  return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer);
1845 }

References GNUNET_CONTAINER_multipeermap_contains(), and peer.

Referenced by compute_rand_delay().

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

1857 {
1859  &peer_ctx->peer_id));
1860  (void) get_channel (peer_ctx);
1861 }

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

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

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

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

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

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

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

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

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

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

2146 {
2147  unsigned int i;
2148 
2150  "Printing peer list of length %u at %p:\n",
2151  len,
2152  list);
2153  for (i = 0; i < len; i++)
2154  {
2156  "%u. peer: %s\n",
2157  i, GNUNET_i2s (&list[i]));
2158  }
2159 }
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(), len, 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 2166 of file gnunet-service-rps.c.

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

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

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

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

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

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

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

2263 {
2264  struct GNUNET_MQ_Envelope *ev;
2265  struct GNUNET_RPS_CS_DEBUG_ViewReply *out_msg;
2266  struct Sub *sub;
2267 
2268  if (NULL == view_array)
2269  {
2270  if (NULL == cli_ctx->sub)
2271  sub = msub;
2272  else
2273  sub = cli_ctx->sub;
2274  view_size = View_size (sub->view);
2275  view_array = View_get_as_array (sub->view);
2276  }
2277 
2278  ev = GNUNET_MQ_msg_extra (out_msg,
2279  view_size * sizeof(struct GNUNET_PeerIdentity),
2281  out_msg->num_peers = htonl (view_size);
2282 
2283  GNUNET_memcpy (&out_msg[1],
2284  view_array,
2285  view_size * sizeof(struct GNUNET_PeerIdentity));
2286  GNUNET_MQ_send (cli_ctx->mq, ev);
2287 }
#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:52
#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 2300 of file gnunet-service-rps.c.

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

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

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

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

References check_peer_known(), clients_notify_stream_peer(), clients_notify_view_update(), GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s_full(), GNUNET_OK, GNUNET_YES, ids, 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 2450 of file gnunet-service-rps.c.

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

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

2577 {
2578  struct Sub *sub = cls;
2579 
2581 }

References CustomPeerMap_put(), peer, and Sub::pull_map.

Referenced by compute_rand_delay().

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

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

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

References get_peer_ctx(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, insert_in_sampler(), insert_in_view_op(), issue_peer_online_check(), msub, peer, 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 2704 of file gnunet-service-rps.c.

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

2744 {
2745  (void) View_remove_peer (sub->view,
2746  peer);
2748  peer);
2750  peer);
2752  peer);
2753  /* We want to destroy the peer now.
2754  * Sometimes, it just seems that it's already been removed from the peer_map,
2755  * so check the peer_map first. */
2756  if (GNUNET_YES == check_peer_known (sub->peer_map,
2757  peer))
2758  {
2760  peer));
2761  }
2762 }
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, peer, 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 2774 of file gnunet-service-rps.c.

2776 {
2778  peer)))
2779  {
2781  "Going to remove send channel to peer %s\n",
2782  GNUNET_i2s (peer));
2783  #if ENABLE_MALICIOUS
2784  if (0 != GNUNET_memcmp (&attacked_peer,
2785  peer))
2787  peer));
2788  #else /* ENABLE_MALICIOUS */
2790  peer));
2791  #endif /* ENABLE_MALICIOUS */
2792  }
2793 
2795  peer))
2796  {
2797  /* Peer was already removed by callback on destroyed channel */
2799  "Peer was removed from our knowledge during cleanup\n");
2800  return;
2801  }
2802 
2804  peer))) &&
2805  (GNUNET_NO == View_contains_peer (sub->view, peer)) &&
2808  (0 == RPS_sampler_count_id (sub->sampler, peer)) &&
2810  { /* We can safely remove this peer */
2812  "Going to remove peer %s\n",
2813  GNUNET_i2s (peer));
2814  remove_peer (sub, peer);
2815  return;
2816  }
2817 }
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, peer, 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 compute_rand_delay(), and do_round().

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

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

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

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

3128 {
3129  (void) cls;
3130  (void) my_identity;
3131 
3133 }
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.

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

Referenced by run().

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

◆ core_connects()

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

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

3148 {
3149  (void) cls;
3150  (void) mq;
3151 
3154  peer,
3155  NULL,
3157  return NULL;
3158 }

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

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

3173 {
3174  (void) cls;
3175  (void) peer_cls;
3176 
3178 }

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

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

3193 {
3194  GNUNET_assert (NULL != cli_ctx);
3196  cli_ctx_tail,
3197  cli_ctx);
3198  if (NULL != cli_ctx->sub)
3199  {
3200  destroy_sub (cli_ctx->sub);
3201  cli_ctx->sub = NULL;
3202  }
3203  GNUNET_free (cli_ctx);
3204 }
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 3215 of file gnunet-service-rps.c.

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

3273 {
3274  (void) cls;
3275  (void) timestamp;
3276  struct ClientContext *cli_ctx_iter;
3277 
3278  adapt_sizes (msub, logestimate, std_dev);
3279  for (cli_ctx_iter = cli_ctx_head;
3280  NULL != cli_ctx_iter;
3281  cli_ctx_iter = cli_ctx_iter->next)
3282  {
3283  if (NULL != cli_ctx_iter->sub)
3284  {
3285  adapt_sizes (cli_ctx_iter->sub, logestimate, std_dev);
3286  }
3287  }
3288 }
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 3301 of file gnunet-service-rps.c.

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

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

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