GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-dht_neighbours.c File Reference

GNUnet DHT service's bucket and neighbour management code. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_block_lib.h"
#include "gnunet_hello_lib.h"
#include "gnunet_constants.h"
#include "gnunet_protocols.h"
#include "gnunet_nse_service.h"
#include "gnunet_ats_service.h"
#include "gnunet_core_service.h"
#include "gnunet_datacache_lib.h"
#include "gnunet_transport_service.h"
#include "gnunet_dht_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet-service-dht.h"
#include "gnunet-service-dht_datacache.h"
#include "gnunet-service-dht_hello.h"
#include "gnunet-service-dht_neighbours.h"
#include "gnunet-service-dht_nse.h"
#include "gnunet-service-dht_routing.h"
#include "dht.h"
Include dependency graph for gnunet-service-dht_neighbours.c:

Go to the source code of this file.

Data Structures

struct  PeerPutMessage
 P2P PUT message. More...
 
struct  PeerResultMessage
 P2P Result message. More...
 
struct  PeerGetMessage
 P2P GET message. More...
 
struct  PeerInfo
 Entry for a peer in a bucket. More...
 
struct  PeerBucket
 Peers are grouped into buckets. More...
 
struct  ConnectInfo
 Information about a peer that we would like to connect to. More...
 

Macros

#define LOG_TRAFFIC(kind, ...)
 
#define SANITY_CHECKS   1
 Enable slow sanity checks to debug issues. More...
 
#define MAX_BUCKETS   sizeof(struct GNUNET_HashCode) * 8
 How many buckets will we allow total. More...
 
#define DEFAULT_BUCKET_SIZE   8
 What is the maximum number of peers in a given bucket. More...
 
#define FIND_PEER_REPLICATION_LEVEL   4
 Desired replication level for FIND PEER requests. More...
 
#define MAXIMUM_REPLICATION_LEVEL   16
 Maximum allowed replication level for all requests. More...
 
#define MAXIMUM_PENDING_PER_PEER   64
 Maximum allowed number of pending messages per peer. More...
 
#define DHT_MINIMUM_FIND_PEER_INTERVAL
 How long at least to wait before sending another find peer request. More...
 
#define DHT_MAXIMUM_FIND_PEER_INTERVAL
 How long at most to wait before sending another find peer request. More...
 
#define GET_TIMEOUT   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
 How long at most to wait for transmission of a GET request to another peer? More...
 

Functions

static int find_bucket (const struct GNUNET_HashCode *hc)
 Find the optimal bucket for this key. More...
 
static void offer_hello_done (void *cls)
 Function called when GNUNET_TRANSPORT_offer_hello() is done. More...
 
static int free_connect_info (void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
 Function called for all entries in all_desired_peers to clean up. More...
 
static void try_connect (const struct GNUNET_PeerIdentity *pid, const struct GNUNET_MessageHeader *h)
 Consider if we want to connect to a given peer, and if so let ATS know. More...
 
static int update_desire_strength (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Function called for each peer in all_desired_peers during update_connect_preferences() if we have reason to adjust the strength of our desire to keep connections to certain peers. More...
 
static void update_connect_preferences ()
 Update our preferences for connectivity as given to ATS. More...
 
static int add_known_to_bloom (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Add each of the peers we already know to the bloom filter of the request so that we don't get duplicate HELLOs. More...
 
static void send_find_peer_message (void *cls)
 Task to send a find peer message for our own peer identifier so that we can find the closest peers in the network to ourselves and attempt to connect to them. More...
 
static void * handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
 Method called whenever a peer connects. More...
 
static void handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
 Method called whenever a peer disconnects. More...
 
static unsigned int get_forward_count (uint32_t hop_count, uint32_t target_replication)
 To how many peers should we (on average) forward the request to obtain the desired target_replication count (on average). More...
 
static unsigned int get_distance (const struct GNUNET_HashCode *target, const struct GNUNET_HashCode *have)
 Compute the distance between have and target as a 32-bit value. More...
 
int GDS_am_closest_peer (const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
 Check whether my identity is closer than any known peers. More...
 
static struct PeerInfoselect_peer (const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hops)
 Select a peer from the routing table that would be a good routing destination for sending a message for "key". More...
 
static unsigned int get_target_peers (const struct GNUNET_HashCode *key, struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hop_count, uint32_t target_replication, struct PeerInfo ***targets)
 Compute the set of peers that the given request should be forwarded to. More...
 
int GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size)
 Perform a PUT operation. More...
 
int GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, uint32_t hop_count, const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, struct GNUNET_CONTAINER_BloomFilter *peer_bf)
 Perform a GET operation. More...
 
void GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
 Handle a reply (route to origin). More...
 
static void core_init (void *cls, const struct GNUNET_PeerIdentity *identity)
 To be called on core init/fail. More...
 
static int check_dht_p2p_put (void *cls, const struct PeerPutMessage *put)
 Check validity of a p2p put request. More...
 
static void handle_dht_p2p_put (void *cls, const struct PeerPutMessage *put)
 Core handler for p2p put requests. More...
 
static void handle_find_peer (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_HashCode *key, struct GNUNET_BLOCK_Group *bg)
 We have received a FIND PEER request. More...
 
static void handle_local_result (void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
 Handle a result from local datacache for a GET operation. More...
 
static int check_dht_p2p_get (void *cls, const struct PeerGetMessage *get)
 Check validity of p2p get request. More...
 
static void handle_dht_p2p_get (void *cls, const struct PeerGetMessage *get)
 Core handler for p2p get requests. More...
 
static int check_dht_p2p_result (void *cls, const struct PeerResultMessage *prm)
 Check validity of p2p result message. More...
 
static void process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
 Process a reply, after the get_path has been updated. More...
 
static void handle_dht_p2p_result (void *cls, const struct PeerResultMessage *prm)
 Core handler for p2p result messages. More...
 
int GDS_NEIGHBOURS_init ()
 Initialize neighbours subsystem. More...
 
void GDS_NEIGHBOURS_done ()
 Shutdown neighbours subsystem. More...
 
struct GNUNET_PeerIdentityGDS_NEIGHBOURS_get_id ()
 Get the ID of the local node. More...
 

Variables

struct GNUNET_TIME_Relative hello_expiration
 Hello address expiration. More...
 
static int cache_results
 Do we cache all results that we are routing in the local datacache? More...
 
static int log_route_details_stderr
 Should routing details be logged to stderr (for debugging)? More...
 
static unsigned int closest_bucket
 The lowest currently used bucket, initially 0 (for 0-bits matching bucket). More...
 
static unsigned int newly_found_peers
 How many peers have we added since we sent out our last find peer request? More...
 
static int disable_try_connect
 Option for testing that disables the 'connect' function of the DHT. More...
 
static struct PeerBucket k_buckets [sizeof(struct GNUNET_HashCode) *8]
 The buckets. More...
 
static struct GNUNET_CONTAINER_MultiPeerMapall_connected_peers
 Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect. More...
 
static struct GNUNET_CONTAINER_MultiPeerMapall_desired_peers
 Hash map of all peers we would like to be connected to. More...
 
static unsigned int bucket_size = 8
 Maximum size for each bucket. More...
 
static struct GNUNET_SCHEDULER_Taskfind_peer_task
 Task that sends FIND PEER requests. More...
 
static struct GNUNET_PeerIdentity my_identity
 Identity of this peer. More...
 
struct GNUNET_HashCode my_identity_hash
 Hash of the identity of this peer. More...
 
static struct GNUNET_CORE_Handlecore_api
 Handle to CORE. More...
 
static struct GNUNET_ATS_ConnectivityHandleats_ch
 Handle to ATS connectivity. More...
 

Detailed Description

GNUnet DHT service's bucket and neighbour management code.

Author
Christian Grothoff
Nathan Evans

Definition in file gnunet-service-dht_neighbours.c.

Macro Definition Documentation

◆ LOG_TRAFFIC

#define LOG_TRAFFIC (   kind,
  ... 
)
Value:
GNUNET_log_from (kind, "dht-traffic", \
__VA_ARGS__)
#define GNUNET_log_from(kind, comp,...)

Definition at line 49 of file gnunet-service-dht_neighbours.c.

Referenced by handle_dht_p2p_get(), handle_dht_p2p_put(), and handle_dht_p2p_result().

◆ SANITY_CHECKS

#define SANITY_CHECKS   1

Enable slow sanity checks to debug issues.

Definition at line 55 of file gnunet-service-dht_neighbours.c.

◆ MAX_BUCKETS

#define MAX_BUCKETS   sizeof(struct GNUNET_HashCode) * 8

How many buckets will we allow total.

Definition at line 60 of file gnunet-service-dht_neighbours.c.

Referenced by find_bucket(), and handle_core_connect().

◆ DEFAULT_BUCKET_SIZE

#define DEFAULT_BUCKET_SIZE   8

What is the maximum number of peers in a given bucket.

Definition at line 65 of file gnunet-service-dht_neighbours.c.

◆ FIND_PEER_REPLICATION_LEVEL

#define FIND_PEER_REPLICATION_LEVEL   4

Desired replication level for FIND PEER requests.

Definition at line 70 of file gnunet-service-dht_neighbours.c.

Referenced by send_find_peer_message().

◆ MAXIMUM_REPLICATION_LEVEL

#define MAXIMUM_REPLICATION_LEVEL   16

Maximum allowed replication level for all requests.

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

Referenced by get_forward_count().

◆ MAXIMUM_PENDING_PER_PEER

#define MAXIMUM_PENDING_PER_PEER   64

Maximum allowed number of pending messages per peer.

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

Referenced by GDS_NEIGHBOURS_handle_get(), GDS_NEIGHBOURS_handle_put(), and GDS_NEIGHBOURS_handle_reply().

◆ DHT_MINIMUM_FIND_PEER_INTERVAL

#define DHT_MINIMUM_FIND_PEER_INTERVAL
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:442

How long at least to wait before sending another find peer request.

Definition at line 85 of file gnunet-service-dht_neighbours.c.

Referenced by send_find_peer_message().

◆ DHT_MAXIMUM_FIND_PEER_INTERVAL

#define DHT_MAXIMUM_FIND_PEER_INTERVAL
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:442

How long at most to wait before sending another find peer request.

Definition at line 91 of file gnunet-service-dht_neighbours.c.

Referenced by send_find_peer_message().

◆ GET_TIMEOUT

How long at most to wait for transmission of a GET request to another peer?

Definition at line 97 of file gnunet-service-dht_neighbours.c.

Function Documentation

◆ find_bucket()

static int find_bucket ( const struct GNUNET_HashCode hc)
static

Find the optimal bucket for this key.

Parameters
hcthe hashcode to compare our identity to
Returns
the proper bucket index, or GNUNET_SYSERR on error (same hashcode)

Definition at line 426 of file gnunet-service-dht_neighbours.c.

References GNUNET_break, GNUNET_CRYPTO_hash_matching_bits(), GNUNET_SYSERR, MAX_BUCKETS, and my_identity_hash.

Referenced by GDS_am_closest_peer(), handle_core_connect(), handle_find_peer(), and try_connect().

427 {
428  unsigned int bits;
429 
431  if (bits == MAX_BUCKETS)
432  {
433  /* How can all bits match? Got my own ID? */
434  GNUNET_break (0);
435  return GNUNET_SYSERR;
436  }
437  return MAX_BUCKETS - bits - 1;
438 }
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:272
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
#define MAX_BUCKETS
How many buckets will we allow total.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ offer_hello_done()

static void offer_hello_done ( void *  cls)
static

Function called when GNUNET_TRANSPORT_offer_hello() is done.

Clean up the "oh" field in the cls

Parameters
clsa struct ConnectInfo

Definition at line 448 of file gnunet-service-dht_neighbours.c.

References ConnectInfo::oh.

Referenced by try_connect().

449 {
450  struct ConnectInfo *ci = cls;
451 
452  ci->oh = NULL;
453 }
struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Handle to active HELLO offer operation, or NULL.
Information about a peer that we would like to connect to.
Here is the caller graph for this function:

◆ free_connect_info()

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

Function called for all entries in all_desired_peers to clean up.

Parameters
clsNULL
peerpeer the entry is for
valuethe value to remove
Returns
GNUNET_YES

Definition at line 465 of file gnunet-service-dht_neighbours.c.

References GNUNET_assert, GNUNET_ATS_connectivity_suggest_cancel(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_free, GNUNET_TRANSPORT_offer_hello_cancel(), GNUNET_YES, ConnectInfo::oh, ConnectInfo::sh, and value.

Referenced by GDS_NEIGHBOURS_done(), and try_connect().

468 {
469  struct ConnectInfo *ci = value;
470 
471  (void) cls;
474  peer,
475  ci));
476  if (NULL != ci->sh)
477  {
479  ci->sh = NULL;
480  }
481  if (NULL != ci->oh)
482  {
484  ci->oh = NULL;
485  }
486  GNUNET_free (ci);
487  return GNUNET_YES;
488 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Handle to active HELLO offer operation, or NULL.
static char * value
Value of the record to add/remove.
Information about a peer that we would like to connect to.
void GNUNET_TRANSPORT_offer_hello_cancel(struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
Cancel the request to transport to offer the HELLO message.
struct GNUNET_ATS_ConnectivitySuggestHandle * sh
Handle to active connectivity suggestion operation, or NULL.
static struct GNUNET_CONTAINER_MultiPeerMap * all_desired_peers
Hash map of all peers we would like to be connected to.
#define GNUNET_YES
Definition: gnunet_common.h:77
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_connect()

static void try_connect ( const struct GNUNET_PeerIdentity pid,
const struct GNUNET_MessageHeader h 
)
static

Consider if we want to connect to a given peer, and if so let ATS know.

If applicable, the HELLO is offered to the TRANSPORT service.

Parameters
pidpeer to consider connectivity requirements for
ha HELLO message, or NULL

Definition at line 500 of file gnunet-service-dht_neighbours.c.

References bucket_size, find_bucket(), free_connect_info(), GDS_cfg, GNUNET_assert, GNUNET_ATS_connectivity_suggest(), GNUNET_ATS_connectivity_suggest_cancel(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_CRYPTO_hash(), GNUNET_new, GNUNET_OK, GNUNET_TRANSPORT_offer_hello(), GNUNET_TRANSPORT_offer_hello_cancel(), GNUNET_YES, k_buckets, offer_hello_done(), ConnectInfo::oh, PeerBucket::peers_size, ConnectInfo::sh, and ConnectInfo::strength.

Referenced by handle_dht_p2p_result(), and update_desire_strength().

502 {
503  int bucket;
504  struct GNUNET_HashCode pid_hash;
505  struct ConnectInfo *ci;
506  uint32_t strength;
507 
508  GNUNET_CRYPTO_hash (pid,
509  sizeof(struct GNUNET_PeerIdentity),
510  &pid_hash);
511  bucket = find_bucket (&pid_hash);
512  if (bucket < 0)
513  return; /* self? */
515  pid);
516 
517  if (k_buckets[bucket].peers_size < bucket_size)
518  strength = (bucket_size - k_buckets[bucket].peers_size) * bucket;
519  else
520  strength = bucket; /* minimum value of connectivity */
521  if (GNUNET_YES ==
523  pid))
524  strength *= 2; /* double for connected peers */
525  else if (k_buckets[bucket].peers_size > bucket_size)
526  strength = 0; /* bucket full, we really do not care about more */
527 
528  if ((0 == strength) &&
529  (NULL != ci))
530  {
531  /* release request */
533  free_connect_info (NULL,
534  pid,
535  ci));
536  return;
537  }
538  if (NULL == ci)
539  {
540  ci = GNUNET_new (struct ConnectInfo);
543  pid,
544  ci,
546  }
547  if ((NULL != ci->oh) &&
548  (NULL != h))
550  if (NULL != h)
552  h,
554  ci);
555  if ((NULL != ci->sh) &&
556  (ci->strength != strength))
558  if (ci->strength != strength)
560  pid,
561  strength);
562  ci->strength = strength;
563 }
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int find_bucket(const struct GNUNET_HashCode *hc)
Find the optimal bucket for this key.
unsigned int peers_size
Number of peers in the bucket.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
struct GNUNET_ATS_ConnectivitySuggestHandle * GNUNET_ATS_connectivity_suggest(struct GNUNET_ATS_ConnectivityHandle *ch, const struct GNUNET_PeerIdentity *peer, uint32_t strength)
We would like to receive address suggestions for a peer.
static int free_connect_info(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Function called for all entries in all_desired_peers to clean up.
struct GNUNET_TRANSPORT_OfferHelloHandle * oh
Handle to active HELLO offer operation, or NULL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
Information about a peer that we would like to connect to.
A 512-bit hashcode.
void GNUNET_TRANSPORT_offer_hello_cancel(struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
Cancel the request to transport to offer the HELLO message.
struct GNUNET_ATS_ConnectivitySuggestHandle * sh
Handle to active connectivity suggestion operation, or NULL.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
uint32_t strength
How much would we like to connect to this peer?
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.
The identity of the host (wraps the signing key of the peer).
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.
struct GNUNET_TRANSPORT_OfferHelloHandle * GNUNET_TRANSPORT_offer_hello(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_MessageHeader *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Offer the transport service the HELLO of another peer.
static struct GNUNET_ATS_ConnectivityHandle * ats_ch
Handle to ATS connectivity.
static unsigned int bucket_size
Maximum size for each bucket.
static struct GNUNET_CONTAINER_MultiPeerMap * all_desired_peers
Hash map of all peers we would like to be connected to.
#define GNUNET_YES
Definition: gnunet_common.h:77
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
Configuration we use.
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)...
static void offer_hello_done(void *cls)
Function called when GNUNET_TRANSPORT_offer_hello() is done.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_desire_strength()

static int update_desire_strength ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Function called for each peer in all_desired_peers during update_connect_preferences() if we have reason to adjust the strength of our desire to keep connections to certain peers.

Calls try_connect() to update the calculations for the given pid.

Parameters
clsNULL
pidpeer to update
valueunused
Returns
GNUNET_YES (continue to iterate)

Definition at line 579 of file gnunet-service-dht_neighbours.c.

References GNUNET_YES, and try_connect().

Referenced by update_connect_preferences().

582 {
583  (void) cls;
584  (void) value;
585  try_connect (pid,
586  NULL);
587  return GNUNET_YES;
588 }
static char * value
Value of the record to add/remove.
static void try_connect(const struct GNUNET_PeerIdentity *pid, const struct GNUNET_MessageHeader *h)
Consider if we want to connect to a given peer, and if so let ATS know.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_connect_preferences()

static void update_connect_preferences ( )
static

Update our preferences for connectivity as given to ATS.

Parameters
clsthe struct PeerInfo of the peer
tcscheduler context.

Definition at line 598 of file gnunet-service-dht_neighbours.c.

References GNUNET_CONTAINER_multipeermap_iterate(), and update_desire_strength().

Referenced by handle_core_connect(), and handle_core_disconnect().

599 {
602  NULL);
603 }
static int update_desire_strength(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Function called for each peer in all_desired_peers during update_connect_preferences() if we have rea...
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static struct GNUNET_CONTAINER_MultiPeerMap * all_desired_peers
Hash map of all peers we would like to be connected to.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_known_to_bloom()

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

Add each of the peers we already know to the bloom filter of the request so that we don't get duplicate HELLOs.

Parameters
clsthe struct GNUNET_BLOCK_Group
keypeer identity to add to the bloom filter
valuevalue the peer information (unused)
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 616 of file gnunet-service-dht_neighbours.c.

References GNUNET_BLOCK_group_set_seen(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, and GNUNET_YES.

Referenced by send_find_peer_message().

619 {
620  struct GNUNET_BLOCK_Group *bg = cls;
621  struct GNUNET_HashCode key_hash;
622 
623  (void) cls;
624  (void) value;
625  GNUNET_CRYPTO_hash (key,
626  sizeof(struct GNUNET_PeerIdentity),
627  &key_hash);
629  &key_hash,
630  1);
632  "Adding known peer (%s) to bloomfilter for FIND PEER\n",
633  GNUNET_i2s (key));
634  return GNUNET_YES;
635 }
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
Block group data.
#define GNUNET_YES
Definition: gnunet_common.h:77
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int GNUNET_BLOCK_group_set_seen(struct GNUNET_BLOCK_Group *bg, const struct GNUNET_HashCode *seen_results, unsigned int seen_results_count)
Update block group to filter out the given results.
Definition: block.c:409
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_find_peer_message()

static void send_find_peer_message ( void *  cls)
static

Task to send a find peer message for our own peer identifier so that we can find the closest peers in the network to ourselves and attempt to connect to them.

Parameters
clsclosure for this task

Definition at line 646 of file gnunet-service-dht_neighbours.c.

References add_known_to_bloom(), bucket_size, DHT_BLOOM_SIZE, DHT_MAXIMUM_FIND_PEER_INTERVAL, DHT_MINIMUM_FIND_PEER_INTERVAL, FIND_PEER_REPLICATION_LEVEL, GDS_block_context, GDS_NEIGHBOURS_handle_get(), GDS_stats, gettext_noop, GNUNET_assert, GNUNET_BLOCK_group_create(), GNUNET_BLOCK_group_destroy(), GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_CRYPTO_random_u64(), GNUNET_DHT_RO_FIND_PEER, GNUNET_DHT_RO_RECORD_ROUTE, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TIME_UNIT_MINUTES, my_identity_hash, newly_found_peers, and GNUNET_TIME_Relative::rel_value_us.

Referenced by handle_core_connect().

647 {
648  struct GNUNET_TIME_Relative next_send_time;
649  struct GNUNET_BLOCK_Group *bg;
650  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
651 
652  (void) cls;
653  find_peer_task = NULL;
655  {
656  /* If we are finding many peers already, no need to send out our request right now! */
660  NULL);
661  newly_found_peers = 0;
662  return;
663  }
668  UINT32_MAX),
669  NULL,
670  0,
671  "filter-size",
673  NULL);
676  bg);
678  gettext_noop ("# FIND PEER messages initiated"),
679  1,
680  GNUNET_NO);
681  peer_bf
685  // FIXME: pass priority!?
690  0,
692  NULL,
693  0,
694  bg,
695  peer_bf);
698  /* schedule next round */
699  next_send_time.rel_value_us =
700  DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value_us
702  DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value_us
703  / (newly_found_peers + 1));
704  newly_found_peers = 0;
705  GNUNET_assert (NULL == find_peer_task);
707  GNUNET_SCHEDULER_add_delayed (next_send_time,
709  NULL);
710 }
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
We should keep track of the route that the message took in the P2P network.
#define DHT_MINIMUM_FIND_PEER_INTERVAL
How long at least to wait before sending another find peer request.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
#define GNUNET_TIME_UNIT_MINUTES
One minute.
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in &#39;GET&#39; queries.
static struct GNUNET_SCHEDULER_Task * find_peer_task
Task that sends FIND PEER requests.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static unsigned int newly_found_peers
How many peers have we added since we sent out our last find peer request?
#define FIND_PEER_REPLICATION_LEVEL
Desired replication level for FIND PEER requests.
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
static int add_known_to_bloom(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Add each of the peers we already know to the bloom filter of the request so that we don&#39;t get duplica...
#define DHT_MAXIMUM_FIND_PEER_INTERVAL
How long at most to wait before sending another find peer request.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
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:1253
This is a &#39;FIND-PEER&#39; request, so approximate results are fine.
Type of a block that contains a HELLO for a peer (for DHT and CADET find-peer operations).
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_group_create(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, uint32_t nonce, const void *raw_data, size_t raw_data_size,...)
Create a new block group.
Definition: block.c:289
int GDS_NEIGHBOURS_handle_get(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, uint32_t hop_count, const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, struct GNUNET_CONTAINER_BloomFilter *peer_bf)
Perform a GET operation.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static void send_find_peer_message(void *cls)
Task to send a find peer message for our own peer identifier so that we can find the closest peers in...
Block group data.
static unsigned int bucket_size
Maximum size for each bucket.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
Time for relative time used by GNUnet, in microseconds.
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:205
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_core_connect()

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

Method called whenever a peer connects.

Parameters
clsclosure
peerpeer identity this notification is about
mqmessage queue for sending messages to peer
Returns
our struct PeerInfo for peer

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

References bucket_size, closest_bucket, disable_try_connect, find_bucket(), GDS_stats, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MAX, GNUNET_memcmp, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_STATISTICS_update(), GNUNET_YES, PeerBucket::head, PeerInfo::id, k_buckets, MAX_BUCKETS, mq, PeerInfo::mq, my_identity, newly_found_peers, peer, PeerInfo::peer_bucket, PeerBucket::peers_size, PeerInfo::phash, pi, send_find_peer_message(), PeerBucket::tail, and update_connect_preferences().

Referenced by GDS_NEIGHBOURS_init().

725 {
726  struct PeerInfo *pi;
727 
728  (void) cls;
729  /* Check for connect to self message */
730  if (0 == GNUNET_memcmp (&my_identity,
731  peer))
732  return NULL;
734  "Connected to %s\n",
735  GNUNET_i2s (peer));
738  peer));
740  gettext_noop ("# peers connected"),
741  1,
742  GNUNET_NO);
743  pi = GNUNET_new (struct PeerInfo);
744  pi->id = peer;
745  pi->mq = mq;
746  GNUNET_CRYPTO_hash (peer,
747  sizeof(struct GNUNET_PeerIdentity),
748  &pi->phash);
749  pi->peer_bucket = find_bucket (&pi->phash);
750  GNUNET_assert ((pi->peer_bucket >= 0) &&
751  ((unsigned int) pi->peer_bucket < MAX_BUCKETS));
754  pi);
757  (unsigned int) pi->peer_bucket);
760  pi->id,
761  pi,
763  if ((pi->peer_bucket > 0) &&
765  {
768  }
771  {
772  /* got a first connection, good time to start with FIND PEER requests... */
773  GNUNET_assert (NULL == find_peer_task);
775  NULL);
776  }
777  return pi;
778 }
static unsigned int closest_bucket
The lowest currently used bucket, initially 0 (for 0-bits matching bucket).
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
static void update_connect_preferences()
Update our preferences for connectivity as given to ATS.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_Task * find_peer_task
Task that sends FIND PEER requests.
struct PeerInfo * head
Head of DLL.
static int find_bucket(const struct GNUNET_HashCode *hc)
Find the optimal bucket for this key.
unsigned int peers_size
Number of peers in the bucket.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_HashCode phash
Hash of id.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
static unsigned int newly_found_peers
How many peers have we added since we sent out our last find peer request?
static int disable_try_connect
Option for testing that disables the &#39;connect&#39; function of the DHT.
int peer_bucket
Which bucket is this peer in?
#define MAX_BUCKETS
How many buckets will we allow total.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
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:1280
struct PeerInfo * tail
Tail of DLL.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Entry for a peer in a bucket.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
The identity of the host (wraps the signing key of the peer).
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
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.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
static void send_find_peer_message(void *cls)
Task to send a find peer message for our own peer identifier so that we can find the closest peers in...
static unsigned int bucket_size
Maximum size for each bucket.
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_MQ_Handle * mq
Handle for sending messages to this peer.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_core_disconnect()

static void handle_core_disconnect ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  internal_cls 
)
static

Method called whenever a peer disconnects.

Parameters
clsclosure
peerpeer identity this notification is about
internal_clsour struct PeerInfo for peer

Definition at line 789 of file gnunet-service-dht_neighbours.c.

References bucket_size, closest_bucket, disable_try_connect, GDS_stats, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, PeerBucket::head, k_buckets, PeerInfo::peer_bucket, PeerBucket::peers_size, PeerBucket::tail, and update_connect_preferences().

Referenced by GDS_NEIGHBOURS_init().

792 {
793  struct PeerInfo *to_remove = internal_cls;
794 
795  (void) cls;
796  /* Check for disconnect from self message */
797  if (NULL == to_remove)
798  return;
800  "Disconnected %s\n",
801  GNUNET_i2s (peer));
803  gettext_noop ("# peers connected"),
804  -1,
805  GNUNET_NO);
808  peer,
809  to_remove));
812  {
814  find_peer_task = NULL;
815  }
816  GNUNET_assert (to_remove->peer_bucket >= 0);
818  k_buckets[to_remove->peer_bucket].tail,
819  to_remove);
820  GNUNET_assert (k_buckets[to_remove->peer_bucket].peers_size > 0);
821  k_buckets[to_remove->peer_bucket].peers_size--;
822  while ((closest_bucket > 0) &&
823  (0 == k_buckets[to_remove->peer_bucket].peers_size))
824  closest_bucket--;
825  if (k_buckets[to_remove->peer_bucket].peers_size < bucket_size)
827  GNUNET_free (to_remove);
828 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static unsigned int closest_bucket
The lowest currently used bucket, initially 0 (for 0-bits matching bucket).
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
static void update_connect_preferences()
Update our preferences for connectivity as given to ATS.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_Task * find_peer_task
Task that sends FIND PEER requests.
struct PeerInfo * head
Head of DLL.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
unsigned int peers_size
Number of peers in the bucket.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int disable_try_connect
Option for testing that disables the &#39;connect&#39; function of the DHT.
int peer_bucket
Which bucket is this peer in?
struct PeerInfo * tail
Tail of DLL.
Entry for a peer in a bucket.
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
#define GNUNET_log(kind,...)
static unsigned int bucket_size
Maximum size for each bucket.
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_forward_count()

static unsigned int get_forward_count ( uint32_t  hop_count,
uint32_t  target_replication 
)
static

To how many peers should we (on average) forward the request to obtain the desired target_replication count (on average).

Parameters
hop_countnumber of hops the message has traversed
target_replicationthe number of total paths desired
Returns
Some number of peers to forward the message to

Definition at line 840 of file gnunet-service-dht_neighbours.c.

References GDS_NSE_get(), GDS_stats, gettext_noop, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_MIN, GNUNET_NO, GNUNET_STATISTICS_update(), PeerPutMessage::hop_count, and MAXIMUM_REPLICATION_LEVEL.

Referenced by get_target_peers().

842 {
843  uint32_t random_value;
844  uint32_t forward_count;
845  float target_value;
846 
847  if (hop_count > GDS_NSE_get () * 4.0)
848  {
849  /* forcefully terminate */
851  gettext_noop ("# requests TTL-dropped"),
852  1, GNUNET_NO);
853  return 0;
854  }
855  if (hop_count > GDS_NSE_get () * 2.0)
856  {
857  /* Once we have reached our ideal number of hops, only forward to 1 peer */
858  return 1;
859  }
860  /* bound by system-wide maximum */
861  target_replication =
862  GNUNET_MIN (MAXIMUM_REPLICATION_LEVEL, target_replication);
863  target_value =
864  1 + (target_replication - 1.0) / (GDS_NSE_get ()
865  + ((float) (target_replication - 1.0)
866  * hop_count));
867  /* Set forward count to floor of target_value */
868  forward_count = (uint32_t) target_value;
869  /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */
870  target_value = target_value - forward_count;
871  random_value =
873  if (random_value < (target_value * UINT32_MAX))
874  forward_count++;
875  return forward_count;
876 }
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_NO
Definition: gnunet_common.h:78
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 GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
#define MAXIMUM_REPLICATION_LEVEL
Maximum allowed replication level for all requests.
double GDS_NSE_get()
Return the log of the current network size estimate.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_distance()

static unsigned int get_distance ( const struct GNUNET_HashCode target,
const struct GNUNET_HashCode have 
)
static

Compute the distance between have and target as a 32-bit value.

Differences in the lower bits must count stronger than differences in the higher bits.

Parameters
target
have
Returns
0 if have==target, otherwise a number that is larger as the distance between the two hash codes increases

Definition at line 891 of file gnunet-service-dht_neighbours.c.

References GNUNET_CRYPTO_hash_get_bit(), and GNUNET_CRYPTO_hash_matching_bits().

Referenced by select_peer().

893 {
894  unsigned int bucket;
895  unsigned int msb;
896  unsigned int lsb;
897  unsigned int i;
898 
899  /* We have to represent the distance between two 2^9 (=512)-bit
900  * numbers as a 2^5 (=32)-bit number with "0" being used for the
901  * two numbers being identical; furthermore, we need to
902  * guarantee that a difference in the number of matching
903  * bits is always represented in the result.
904  *
905  * We use 2^32/2^9 numerical values to distinguish between
906  * hash codes that have the same LSB bit distance and
907  * use the highest 2^9 bits of the result to signify the
908  * number of (mis)matching LSB bits; if we have 0 matching
909  * and hence 512 mismatching LSB bits we return -1 (since
910  * 512 itself cannot be represented with 9 bits) *//* first, calculate the most significant 9 bits of our
911  * result, aka the number of LSBs */bucket = GNUNET_CRYPTO_hash_matching_bits (target,
912  have);
913  /* bucket is now a value between 0 and 512 */
914  if (bucket == 512)
915  return 0; /* perfect match */
916  if (bucket == 0)
917  return (unsigned int) -1; /* LSB differs; use max (if we did the bit-shifting
918  * below, we'd end up with max+1 (overflow)) */
919 
920  /* calculate the most significant bits of the final result */
921  msb = (512 - bucket) << (32 - 9);
922  /* calculate the 32-9 least significant bits of the final result by
923  * looking at the differences in the 32-9 bits following the
924  * mismatching bit at 'bucket' */
925  lsb = 0;
926  for (i = bucket + 1;
927  (i < sizeof(struct GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9);
928  i++)
929  {
930  if (GNUNET_CRYPTO_hash_get_bit (target, i) !=
931  GNUNET_CRYPTO_hash_get_bit (have, i))
932  lsb |= (1 << (bucket + 32 - 9 - i)); /* first bit set will be 10,
933  * last bit set will be 31 -- if
934  * i does not reach 512 first... */
935  }
936  return msb | lsb;
937 }
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:272
A 512-bit hashcode.
int GNUNET_CRYPTO_hash_get_bit(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:251
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_am_closest_peer()

int GDS_am_closest_peer ( const struct GNUNET_HashCode key,
const struct GNUNET_CONTAINER_BloomFilter bloom 
)

Check whether my identity is closer than any known peers.

If a non-null bloomfilter is given, check if this is the closest peer that hasn't already been routed to.

Parameters
keyhash code to check closeness to
bloombloomfilter, exclude these entries from the decision
Returns
GNUNET_YES if node location is closest, GNUNET_NO otherwise.

Definition at line 951 of file gnunet-service-dht_neighbours.c.

References GNUNET_HashCode::bits, find_bucket(), GNUNET_assert, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_hash_matching_bits(), GNUNET_memcmp, GNUNET_NO, GNUNET_YES, PeerBucket::head, k_buckets, my_identity_hash, PeerInfo::next, and PeerInfo::phash.

Referenced by handle_dht_p2p_get(), and handle_dht_p2p_put().

953 {
954  int bits;
955  int other_bits;
956  int bucket_num;
957  struct PeerInfo *pos;
958 
959  if (0 == GNUNET_memcmp (&my_identity_hash,
960  key))
961  return GNUNET_YES;
962  bucket_num = find_bucket (key);
963  GNUNET_assert (bucket_num >= 0);
965  key);
966  pos = k_buckets[bucket_num].head;
967  while (NULL != pos)
968  {
969  if ((NULL != bloom) &&
970  (GNUNET_YES ==
972  &pos->phash)))
973  {
974  pos = pos->next;
975  continue; /* Skip already checked entries */
976  }
977  other_bits = GNUNET_CRYPTO_hash_matching_bits (&pos->phash,
978  key);
979  if (other_bits > bits)
980  return GNUNET_NO;
981  if (other_bits == bits) /* We match the same number of bits */
982  return GNUNET_YES;
983  pos = pos->next;
984  }
985  /* No peers closer, we are the closest! */
986  return GNUNET_YES;
987 }
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
struct PeerInfo * next
Next peer entry (DLL)
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:272
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct PeerInfo * head
Head of DLL.
static int find_bucket(const struct GNUNET_HashCode *hc)
Find the optimal bucket for this key.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_HashCode phash
Hash of id.
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
Entry for a peer in a bucket.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_YES
Definition: gnunet_common.h:77
uint32_t bits[512/8/sizeof(uint32_t)]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_peer()

static struct PeerInfo* select_peer ( const struct GNUNET_HashCode key,
const struct GNUNET_CONTAINER_BloomFilter bloom,
uint32_t  hops 
)
static

Select a peer from the routing table that would be a good routing destination for sending a message for "key".

The resulting peer must not be in the set of blocked peers.

Note that we should not ALWAYS select the closest peer to the target, peers further away from the target should be chosen with exponentially declining probability.

FIXME: double-check that this is fine

Parameters
keythe key we are selecting a peer to route to
blooma bloomfilter containing entries this request has seen already
hopshow many hops has this message traversed thus far
Returns
Peer to route to, or NULL on error

Definition at line 1008 of file gnunet-service-dht_neighbours.c.

References bucket_size, closest_bucket, GDS_NSE_get(), GDS_stats, get_distance(), gettext_noop, GNUNET_break, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, head, PeerBucket::head, PeerInfo::id, k_buckets, PeerInfo::next, and PeerInfo::phash.

Referenced by get_target_peers().

1011 {
1012  unsigned int bc;
1013  unsigned int count;
1014  unsigned int selected;
1015  struct PeerInfo *pos;
1016  unsigned int dist;
1017  unsigned int smallest_distance;
1018  struct PeerInfo *chosen;
1019 
1020  if (hops >= GDS_NSE_get ())
1021  {
1022  /* greedy selection (closest peer that is not in bloomfilter) */
1023  smallest_distance = UINT_MAX;
1024  chosen = NULL;
1025  for (bc = 0; bc <= closest_bucket; bc++)
1026  {
1027  pos = k_buckets[bc].head;
1028  count = 0;
1029  while ((pos != NULL) && (count < bucket_size))
1030  {
1031  if ((NULL == bloom) ||
1032  (GNUNET_NO ==
1034  &pos->phash)))
1035  {
1036  dist = get_distance (key,
1037  &pos->phash);
1038  if (dist < smallest_distance)
1039  {
1040  chosen = pos;
1041  smallest_distance = dist;
1042  }
1043  }
1044  else
1045  {
1047  "Excluded peer `%s' due to BF match in greedy routing for %s\n",
1048  GNUNET_i2s (pos->id),
1049  GNUNET_h2s (key));
1051  gettext_noop (
1052  "# Peers excluded from routing due to Bloomfilter"),
1053  1,
1054  GNUNET_NO);
1055  dist = get_distance (key,
1056  &pos->phash);
1057  if (dist < smallest_distance)
1058  {
1059  chosen = NULL;
1060  smallest_distance = dist;
1061  }
1062  }
1063  count++;
1064  pos = pos->next;
1065  }
1066  }
1067  if (NULL == chosen)
1069  gettext_noop ("# Peer selection failed"),
1070  1,
1071  GNUNET_NO);
1072  else
1074  "Selected peer `%s' in greedy routing for %s\n",
1075  GNUNET_i2s (chosen->id),
1076  GNUNET_h2s (key));
1077  return chosen;
1078  }
1079 
1080  /* select "random" peer */
1081  /* count number of peers that are available and not filtered */
1082  count = 0;
1083  for (bc = 0; bc <= closest_bucket; bc++)
1084  {
1085  pos = k_buckets[bc].head;
1086  while ((NULL != pos) && (count < bucket_size))
1087  {
1088  if ((NULL != bloom) &&
1089  (GNUNET_YES ==
1091  &pos->phash)))
1092  {
1094  gettext_noop
1095  (
1096  "# Peers excluded from routing due to Bloomfilter"),
1097  1, GNUNET_NO);
1099  "Excluded peer `%s' due to BF match in random routing for %s\n",
1100  GNUNET_i2s (pos->id),
1101  GNUNET_h2s (key));
1102  pos = pos->next;
1103  continue; /* Ignore bloomfiltered peers */
1104  }
1105  count++;
1106  pos = pos->next;
1107  }
1108  }
1109  if (0 == count) /* No peers to select from! */
1110  {
1112  gettext_noop ("# Peer selection failed"), 1,
1113  GNUNET_NO);
1114  return NULL;
1115  }
1116  /* Now actually choose a peer */
1118  count);
1119  count = 0;
1120  for (bc = 0; bc <= closest_bucket; bc++)
1121  {
1122  for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size));
1123  pos = pos->next)
1124  {
1125  if ((bloom != NULL) &&
1126  (GNUNET_YES ==
1128  &pos->phash)))
1129  {
1130  continue; /* Ignore bloomfiltered peers */
1131  }
1132  if (0 == selected--)
1133  {
1135  "Selected peer `%s' in random routing for %s\n",
1136  GNUNET_i2s (pos->id),
1137  GNUNET_h2s (key));
1138  return pos;
1139  }
1140  }
1141  }
1142  GNUNET_break (0);
1143  return NULL;
1144 }
static unsigned int closest_bucket
The lowest currently used bucket, initially 0 (for 0-bits matching bucket).
static unsigned int get_distance(const struct GNUNET_HashCode *target, const struct GNUNET_HashCode *have)
Compute the distance between have and target as a 32-bit value.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
struct PeerInfo * next
Next peer entry (DLL)
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
struct PeerInfo * head
Head of DLL.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashCode phash
Hash of id.
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 GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
Entry for a peer in a bucket.
static struct PendingResolutions * head
Head of list of pending resolution requests.
Definition: gnunet-ats.c:230
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
#define GNUNET_log(kind,...)
static unsigned int bucket_size
Maximum size for each bucket.
#define GNUNET_YES
Definition: gnunet_common.h:77
double GDS_NSE_get()
Return the log of the current network size estimate.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_target_peers()

static unsigned int get_target_peers ( const struct GNUNET_HashCode key,
struct GNUNET_CONTAINER_BloomFilter bloom,
uint32_t  hop_count,
uint32_t  target_replication,
struct PeerInfo ***  targets 
)
static

Compute the set of peers that the given request should be forwarded to.

Parameters
keyrouting key
bloombloom filter excluding peers as targets, all selected peers will be added to the bloom filter
hop_countnumber of hops the request has traversed so far
target_replicationdesired number of replicas
targetswhere to store an array of target peers (to be free'd by the caller)
Returns
number of peers returned in 'targets'.

Definition at line 1161 of file gnunet-service-dht_neighbours.c.

References get_forward_count(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_new_array, GNUNET_NO, PeerInfo::phash, ret, and select_peer().

Referenced by GDS_NEIGHBOURS_handle_get(), and GDS_NEIGHBOURS_handle_put().

1166 {
1167  unsigned int ret;
1168  unsigned int off;
1169  struct PeerInfo **rtargets;
1170  struct PeerInfo *nxt;
1171 
1172  GNUNET_assert (NULL != bloom);
1173  ret = get_forward_count (hop_count,
1174  target_replication);
1175  if (0 == ret)
1176  {
1177  *targets = NULL;
1178  return 0;
1179  }
1180  rtargets = GNUNET_new_array (ret,
1181  struct PeerInfo *);
1182  for (off = 0; off < ret; off++)
1183  {
1184  nxt = select_peer (key,
1185  bloom,
1186  hop_count);
1187  if (NULL == nxt)
1188  break;
1189  rtargets[off] = nxt;
1192  &nxt->phash));
1194  &nxt->phash);
1195  }
1197  "Selected %u/%u peers at hop %u for %s (target was %u)\n",
1198  off,
1200  (unsigned int) hop_count,
1201  GNUNET_h2s (key),
1202  ret);
1203  if (0 == off)
1204  {
1205  GNUNET_free (rtargets);
1206  *targets = NULL;
1207  return 0;
1208  }
1209  *targets = rtargets;
1211  "Forwarding query `%s' to %u peers (goal was %u peers)\n",
1212  GNUNET_h2s (key),
1213  off,
1214  ret);
1215  return off;
1216 }
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
static struct PeerInfo * select_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hops)
Select a peer from the routing table that would be a good routing destination for sending a message f...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
static unsigned int get_forward_count(uint32_t hop_count, uint32_t target_replication)
To how many peers should we (on average) forward the request to obtain the desired target_replication...
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashCode phash
Hash of id.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
Entry for a peer in a bucket.
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
#define GNUNET_log(kind,...)
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_handle_put()

int GDS_NEIGHBOURS_handle_put ( enum GNUNET_BLOCK_Type  type,
enum GNUNET_DHT_RouteOption  options,
uint32_t  desired_replication_level,
struct GNUNET_TIME_Absolute  expiration_time,
uint32_t  hop_count,
struct GNUNET_CONTAINER_BloomFilter bf,
const struct GNUNET_HashCode key,
unsigned int  put_path_length,
struct GNUNET_PeerIdentity put_path,
const void *  data,
size_t  data_size 
)

Perform a PUT operation.

Forwards the given request to other peers. Does not store the data locally. Does not give the data to local clients. May do nothing if this is the only peer in the network (or if we are the closest peer in the network).

Parameters
typetype of the block
optionsrouting options
desired_replication_leveldesired replication count
expiration_timewhen does the content expire
hop_counthow many hops has this message traversed so far
bfBloom filter of peers this PUT has already traversed
keykey for the content
put_path_lengthnumber of entries in put_path
put_pathpeers this request has traversed so far (if tracked)
datapayload to store
data_sizenumber of bytes in data
Returns
GNUNET_OK if the request was forwarded, GNUNET_NO if not

Definition at line 1240 of file gnunet-service-dht_neighbours.c.

References PeerPutMessage::bloomfilter, data_size, PeerPutMessage::desired_replication_level, DHT_BLOOM_SIZE, env, PeerPutMessage::expiration_time, GDS_stats, get_target_peers(), gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_bloomfilter_get_raw_data(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, GNUNET_MQ_get_length(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), GNUNET_YES, PeerPutMessage::hop_count, PeerInfo::id, PeerPutMessage::key, MAXIMUM_PENDING_PER_PEER, PeerInfo::mq, my_identity, my_identity_hash, PeerPutMessage::options, PeerInfo::phash, PeerPutMessage::put_path_length, and PeerPutMessage::type.

Referenced by handle_dht_local_put(), and handle_dht_p2p_put().

1251 {
1252  unsigned int target_count;
1253  unsigned int i;
1254  struct PeerInfo **targets;
1255  struct PeerInfo *target;
1256  size_t msize;
1257  struct GNUNET_MQ_Envelope *env;
1258  struct PeerPutMessage *ppm;
1259  struct GNUNET_PeerIdentity *pp;
1260  unsigned int skip_count;
1261 
1262  GNUNET_assert (NULL != bf);
1264  "Adding myself (%s) to PUT bloomfilter for %s\n",
1266  GNUNET_h2s (key));
1268  &my_identity_hash);
1270  gettext_noop ("# PUT requests routed"),
1271  1,
1272  GNUNET_NO);
1273  target_count
1274  = get_target_peers (key,
1275  bf,
1276  hop_count,
1277  desired_replication_level,
1278  &targets);
1279  if (0 == target_count)
1280  {
1282  "Routing PUT for %s terminates after %u hops at %s\n",
1283  GNUNET_h2s (key),
1284  (unsigned int) hop_count,
1285  GNUNET_i2s (&my_identity));
1286  return GNUNET_NO;
1287  }
1288  msize = put_path_length * sizeof(struct GNUNET_PeerIdentity) + data_size;
1289  if (msize + sizeof(struct PeerPutMessage)
1291  {
1292  put_path_length = 0;
1293  msize = data_size;
1294  }
1295  if (msize + sizeof(struct PeerPutMessage)
1297  {
1298  GNUNET_break (0);
1299  GNUNET_free (targets);
1300  return GNUNET_NO;
1301  }
1303  gettext_noop (
1304  "# PUT messages queued for transmission"),
1305  target_count,
1306  GNUNET_NO);
1307  skip_count = 0;
1308  for (i = 0; i < target_count; i++)
1309  {
1310  target = targets[i];
1312  {
1313  /* skip */
1315  gettext_noop (
1316  "# P2P messages dropped due to full queue"),
1317  1,
1318  GNUNET_NO);
1319  skip_count++;
1320  continue;
1321  }
1323  "Routing PUT for %s after %u hops to %s\n",
1324  GNUNET_h2s (key),
1325  (unsigned int) hop_count,
1326  GNUNET_i2s (target->id));
1327  env = GNUNET_MQ_msg_extra (ppm,
1328  msize,
1330  ppm->options = htonl (options);
1331  ppm->type = htonl (type);
1332  ppm->hop_count = htonl (hop_count + 1);
1333  ppm->desired_replication_level = htonl (desired_replication_level);
1334  ppm->put_path_length = htonl (put_path_length);
1335  ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1338  &target->phash));
1341  ppm->bloomfilter,
1342  DHT_BLOOM_SIZE));
1343  ppm->key = *key;
1344  pp = (struct GNUNET_PeerIdentity *) &ppm[1];
1345  GNUNET_memcpy (pp,
1346  put_path,
1347  sizeof(struct GNUNET_PeerIdentity) * put_path_length);
1348  GNUNET_memcpy (&pp[put_path_length],
1349  data,
1350  data_size);
1351  GNUNET_MQ_send (target->mq,
1352  env);
1353  }
1354  GNUNET_free (targets);
1355  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1356 }
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define MAXIMUM_PENDING_PER_PEER
Maximum allowed number of pending messages per peer.
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashCode phash
Hash of id.
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 GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE
What is the maximum size for encrypted messages? Note that this number imposes a clear limit on the m...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
#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
struct GNUNET_HashCode key
The key we are storing under.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
uint32_t hop_count
Hop count.
uint32_t desired_replication_level
Replication level for this message.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
struct GNUNET_HashCode key
The key used in the DHT.
Entry for a peer in a bucket.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
int GNUNET_CONTAINER_bloomfilter_get_raw_data(const struct GNUNET_CONTAINER_BloomFilter *bf, char *data, size_t size)
Copy the raw data of this Bloom filter into the given data array.
uint32_t options
Processing options.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
The identity of the host (wraps the signing key of the peer).
uint32_t type
Content type.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:77
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:353
struct GNUNET_MQ_Handle * mq
Handle for sending messages to this peer.
static unsigned int get_target_peers(const struct GNUNET_HashCode *key, struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hop_count, uint32_t target_replication, struct PeerInfo ***targets)
Compute the set of peers that the given request should be forwarded to.
uint32_t data
The data value.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
Peer is storing data in DHT.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_handle_get()

int GDS_NEIGHBOURS_handle_get ( enum GNUNET_BLOCK_Type  type,
enum GNUNET_DHT_RouteOption  options,
uint32_t  desired_replication_level,
uint32_t  hop_count,
const struct GNUNET_HashCode key,
const void *  xquery,
size_t  xquery_size,
struct GNUNET_BLOCK_Group bg,
struct GNUNET_CONTAINER_BloomFilter peer_bf 
)

Perform a GET operation.

Forwards the given request to other peers. Does not lookup the key locally. May do nothing if this is the only peer in the network (or if we are the closest peer in the network).

Parameters
typetype of the block
optionsrouting options
desired_replication_leveldesired replication count
hop_counthow many hops did this request traverse so far?
keykey for the content
xqueryextended query
xquery_sizenumber of bytes in xquery
bggroup to use for filtering replies
peer_bffilter for peers not to select (again)
Returns
GNUNET_OK if the request was forwarded, GNUNET_NO if not

Definition at line 1377 of file gnunet-service-dht_neighbours.c.

References PeerGetMessage::bf_mutator, PeerGetMessage::bloomfilter, PeerGetMessage::desired_replication_level, DHT_BLOOM_SIZE, env, GDS_stats, get_target_peers(), gettext_noop, GNUNET_assert, GNUNET_BLOCK_group_serialize(), GNUNET_break, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_bloomfilter_get_raw_data(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_free_non_null, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, GNUNET_MQ_get_length(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, PeerGetMessage::hop_count, PeerInfo::id, PeerPutMessage::key, PeerGetMessage::key, MAXIMUM_PENDING_PER_PEER, PeerInfo::mq, my_identity, my_identity_hash, PeerGetMessage::options, PeerInfo::phash, PeerGetMessage::type, and PeerGetMessage::xquery_size.

Referenced by handle_dht_p2p_get(), send_find_peer_message(), and transmit_request().

1386 {
1387  unsigned int target_count;
1388  struct PeerInfo **targets;
1389  struct PeerInfo *target;
1390  struct GNUNET_MQ_Envelope *env;
1391  size_t msize;
1392  struct PeerGetMessage *pgm;
1393  char *xq;
1394  size_t reply_bf_size;
1395  void *reply_bf;
1396  unsigned int skip_count;
1397  uint32_t bf_nonce;
1398 
1399  GNUNET_assert (NULL != peer_bf);
1401  gettext_noop ("# GET requests routed"),
1402  1,
1403  GNUNET_NO);
1404  target_count = get_target_peers (key,
1405  peer_bf,
1406  hop_count,
1408  &targets);
1410  "Adding myself (%s) to GET bloomfilter for %s\n",
1412  GNUNET_h2s (key));
1414  &my_identity_hash);
1415  if (0 == target_count)
1416  {
1418  "Routing GET for %s terminates after %u hops at %s\n",
1419  GNUNET_h2s (key),
1420  (unsigned int) hop_count,
1421  GNUNET_i2s (&my_identity));
1422  return GNUNET_NO;
1423  }
1424  if (GNUNET_OK !=
1426  &bf_nonce,
1427  &reply_bf,
1428  &reply_bf_size))
1429  {
1430  reply_bf = NULL;
1431  reply_bf_size = 0;
1433  UINT32_MAX);
1434  }
1435  msize = xquery_size + reply_bf_size;
1436  if (msize + sizeof(struct PeerGetMessage) >= GNUNET_MAX_MESSAGE_SIZE)
1437  {
1438  GNUNET_break (0);
1439  GNUNET_free_non_null (reply_bf);
1440  GNUNET_free (targets);
1441  return GNUNET_NO;
1442  }
1444  gettext_noop (
1445  "# GET messages queued for transmission"),
1446  target_count,
1447  GNUNET_NO);
1448  /* forward request */
1449  skip_count = 0;
1450  for (unsigned int i = 0; i < target_count; i++)
1451  {
1452  target = targets[i];
1454  {
1455  /* skip */
1457  gettext_noop (
1458  "# P2P messages dropped due to full queue"),
1459  1, GNUNET_NO);
1460  skip_count++;
1461  continue;
1462  }
1464  "Routing GET for %s after %u hops to %s\n",
1465  GNUNET_h2s (key),
1466  (unsigned int) hop_count,
1467  GNUNET_i2s (target->id));
1468  env = GNUNET_MQ_msg_extra (pgm,
1469  msize,
1471  pgm->options = htonl (options);
1472  pgm->type = htonl (type);
1473  pgm->hop_count = htonl (hop_count + 1);
1475  pgm->xquery_size = htonl (xquery_size);
1476  pgm->bf_mutator = bf_nonce;
1479  &target->phash));
1482  pgm->bloomfilter,
1483  DHT_BLOOM_SIZE));
1484  pgm->key = *key;
1485  xq = (char *) &pgm[1];
1486  GNUNET_memcpy (xq,
1487  xquery,
1488  xquery_size);
1489  GNUNET_memcpy (&xq[xquery_size],
1490  reply_bf,
1491  reply_bf_size);
1492  GNUNET_MQ_send (target->mq,
1493  env);
1494  }
1495  GNUNET_free (targets);
1496  GNUNET_free_non_null (reply_bf);
1497  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1498 }
uint32_t type
Desired content type.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
uint32_t hop_count
Hop count.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define MAXIMUM_PENDING_PER_PEER
Maximum allowed number of pending messages per peer.
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
struct GNUNET_HashCode phash
Hash of id.
uint32_t options
Processing options.
struct GNUNET_HashCode key
The key we are looking for.
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
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 GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
uint32_t desired_replication_level
Desired replication level for this request.
#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
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
int GNUNET_BLOCK_group_serialize(struct GNUNET_BLOCK_Group *bg, uint32_t *nonce, void **raw_data, size_t *raw_data_size)
Serialize state of a block group.
Definition: block.c:180
#define GNUNET_MESSAGE_TYPE_DHT_P2P_GET
Peer tries to find data in DHT.
uint32_t bf_mutator
Bloomfilter mutator.
struct GNUNET_HashCode key
The key used in the DHT.
Entry for a peer in a bucket.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
int GNUNET_CONTAINER_bloomfilter_get_raw_data(const struct GNUNET_CONTAINER_BloomFilter *bf, char *data, size_t size)
Copy the raw data of this Bloom filter into the given data array.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
uint32_t xquery_size
Size of the extended query.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:77
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:353
struct GNUNET_MQ_Handle * mq
Handle for sending messages to this peer.
static unsigned int get_target_peers(const struct GNUNET_HashCode *key, struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hop_count, uint32_t target_replication, struct PeerInfo ***targets)
Compute the set of peers that the given request should be forwarded to.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_handle_reply()

void GDS_NEIGHBOURS_handle_reply ( const struct GNUNET_PeerIdentity target,
enum GNUNET_BLOCK_Type  type,
struct GNUNET_TIME_Absolute  expiration_time,
const struct GNUNET_HashCode key,
unsigned int  put_path_length,
const struct GNUNET_PeerIdentity put_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity get_path,
const void *  data,
size_t  data_size 
)

Handle a reply (route to origin).

Only forwards the reply back to the given peer. Does not do local caching or forwarding to local clients.

Parameters
targetneighbour that should receive the block (if still connected)
typetype of the block
expiration_timewhen does the content expire
keykey for the content
put_path_lengthnumber of entries in put_path
put_pathpeers the original PUT traversed (if tracked)
get_path_lengthnumber of entries in get_path
get_pathpeers this reply has traversed so far (if tracked)
datapayload of the reply
data_sizenumber of bytes in data

Definition at line 1518 of file gnunet-service-dht_neighbours.c.

References env, PeerResultMessage::expiration_time, GDS_stats, PeerResultMessage::get_path_length, gettext_noop, GNUNET_break, GNUNET_CONTAINER_multipeermap_get(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, GNUNET_MQ_get_length(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), PeerPutMessage::key, PeerResultMessage::key, MAXIMUM_PENDING_PER_PEER, PeerInfo::mq, pi, PeerPutMessage::put_path_length, PeerResultMessage::put_path_length, and PeerResultMessage::type.

Referenced by handle_find_peer(), handle_local_result(), and process().

1528 {
1529  struct PeerInfo *pi;
1530  struct GNUNET_MQ_Envelope *env;
1531  size_t msize;
1532  struct PeerResultMessage *prm;
1533  struct GNUNET_PeerIdentity *paths;
1534 
1535  msize = data_size + (get_path_length + put_path_length)
1536  * sizeof(struct GNUNET_PeerIdentity);
1537  if ((msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1538  (get_path_length >
1539  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
1540  (put_path_length >
1541  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
1543  {
1544  GNUNET_break (0);
1545  return;
1546  }
1548  target);
1549  if (NULL == pi)
1550  {
1551  /* peer disconnected in the meantime, drop reply */
1553  "No matching peer for reply for key %s\n",
1554  GNUNET_h2s (key));
1555  return;
1556  }
1558  {
1559  /* skip */
1561  gettext_noop (
1562  "# P2P messages dropped due to full queue"),
1563  1,
1564  GNUNET_NO);
1566  "Peer queue full, ignoring reply for key %s\n",
1567  GNUNET_h2s (key));
1568  return;
1569  }
1570 
1572  "Forwarding reply for key %s to peer %s\n",
1573  GNUNET_h2s (key),
1574  GNUNET_i2s (target));
1576  gettext_noop
1577  ("# RESULT messages queued for transmission"), 1,
1578  GNUNET_NO);
1579  env = GNUNET_MQ_msg_extra (prm,
1580  msize,
1582  prm->type = htonl (type);
1583  prm->put_path_length = htonl (put_path_length);
1584  prm->get_path_length = htonl (get_path_length);
1585  prm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1586  prm->key = *key;
1587  paths = (struct GNUNET_PeerIdentity *) &prm[1];
1588  GNUNET_memcpy (paths,
1589  put_path,
1590  put_path_length * sizeof(struct GNUNET_PeerIdentity));
1591  GNUNET_memcpy (&paths[put_path_length],
1592  get_path,
1593  get_path_length * sizeof(struct GNUNET_PeerIdentity));
1594  GNUNET_memcpy (&paths[put_path_length + get_path_length],
1595  data,
1596  data_size);
1597  GNUNET_MQ_send (pi->mq,
1598  env);
1599 }
uint32_t type
Content type.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
#define MAXIMUM_PENDING_PER_PEER
Maximum allowed number of pending messages per peer.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint32_t get_path_length
Length of the GET path that follows (if tracked).
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#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
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
struct GNUNET_HashCode key
The key used in the DHT.
Entry for a peer in a bucket.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
The identity of the host (wraps the signing key of the peer).
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.
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
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:353
struct GNUNET_MQ_Handle * mq
Handle for sending messages to this peer.
uint32_t data
The data value.
struct GNUNET_HashCode key
The key of the corresponding GET request.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
Data is returned to peer from DHT.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ core_init()

static void core_init ( void *  cls,
const struct GNUNET_PeerIdentity identity 
)
static

To be called on core init/fail.

Parameters
clsservice closure
identitythe public identity of this peer

Definition at line 1609 of file gnunet-service-dht_neighbours.c.

References GDS_service, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_SERVICE_resume(), identity, my_identity, and my_identity_hash.

Referenced by GDS_NEIGHBOURS_init().

1611 {
1612  (void) cls;
1614  "CORE called, I am %s\n",
1615  GNUNET_i2s (identity));
1616  my_identity = *identity;
1617  GNUNET_CRYPTO_hash (identity,
1618  sizeof(struct GNUNET_PeerIdentity),
1619  &my_identity_hash);
1621 }
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2194
struct GNUNET_SERVICE_Handle * GDS_service
Handle for the service.
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_dht_p2p_put()

static int check_dht_p2p_put ( void *  cls,
const struct PeerPutMessage put 
)
static

Check validity of a p2p put request.

Parameters
clsclosure with the struct PeerInfo of the sender
messagemessage
Returns
GNUNET_OK if the message is valid

Definition at line 1632 of file gnunet-service-dht_neighbours.c.

References GNUNET_break_op, GNUNET_MAX_MESSAGE_SIZE, GNUNET_OK, GNUNET_SYSERR, PeerPutMessage::header, PeerPutMessage::put_path_length, and GNUNET_MessageHeader::size.

1634 {
1635  uint32_t putlen;
1636  uint16_t msize;
1637 
1638  (void) cls;
1639  msize = ntohs (put->header.size);
1640  putlen = ntohl (put->put_path_length);
1641  if ((msize <
1642  sizeof(struct PeerPutMessage)
1643  + putlen * sizeof(struct GNUNET_PeerIdentity)) ||
1644  (putlen >
1645  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)))
1646  {
1647  GNUNET_break_op (0);
1648  return GNUNET_SYSERR;
1649  }
1650  return GNUNET_OK;
1651 }
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_PUT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
The identity of the host (wraps the signing key of the peer).

◆ handle_dht_p2p_put()

static void handle_dht_p2p_put ( void *  cls,
const struct PeerPutMessage put 
)
static

Core handler for p2p put requests.

Parameters
clsclosure with the struct PeerInfo of the sender
messagemessage

Definition at line 1661 of file gnunet-service-dht_neighbours.c.

References PeerPutMessage::bloomfilter, PeerPutMessage::desired_replication_level, DHT_BLOOM_SIZE, PeerPutMessage::expiration_time, GDS_am_closest_peer(), GDS_block_context, GDS_CLIENTS_handle_reply(), GDS_CLIENTS_process_put(), GDS_DATACACHE_handle_put(), GDS_NEIGHBOURS_handle_put(), GDS_stats, gettext_noop, GNUNET_BLOCK_EO_NONE, GNUNET_BLOCK_evaluate(), GNUNET_BLOCK_EVALUATION_OK_DUPLICATE, GNUNET_BLOCK_EVALUATION_OK_LAST, GNUNET_BLOCK_EVALUATION_OK_MORE, GNUNET_BLOCK_EVALUATION_REQUEST_INVALID, GNUNET_BLOCK_EVALUATION_REQUEST_VALID, GNUNET_BLOCK_EVALUATION_RESULT_INVALID, GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT, GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED, GNUNET_BLOCK_get_key(), GNUNET_BLOCK_TYPE_REGEX, GNUNET_break, GNUNET_break_op, GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_hash_matching_bits(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_DHT_RO_LAST_HOP, GNUNET_DHT_RO_RECORD_ROUTE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_h2s(), GNUNET_h2s_full(), GNUNET_i2s(), GNUNET_log, GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_strdup, GNUNET_STRINGS_pp2s(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, PeerPutMessage::header, PeerPutMessage::hop_count, PeerInfo::id, PeerPutMessage::key, log_route_details_stderr, LOG_TRAFFIC, my_identity, my_identity_hash, PeerPutMessage::options, payload, peer, PeerInfo::phash, PeerPutMessage::put_path_length, GNUNET_MessageHeader::size, and PeerPutMessage::type.

1663 {
1664  struct PeerInfo *peer = cls;
1665  const struct GNUNET_PeerIdentity *put_path;
1666  const void *payload;
1667  uint32_t putlen;
1668  uint16_t msize;
1669  size_t payload_size;
1671  struct GNUNET_CONTAINER_BloomFilter *bf;
1672  struct GNUNET_HashCode test_key;
1673  int forwarded;
1674  struct GNUNET_TIME_Absolute exp_time;
1675 
1676  exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time);
1677  if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us)
1678  {
1680  gettext_noop ("# Expired PUTs discarded"),
1681  1,
1682  GNUNET_NO);
1683  return;
1684  }
1685  msize = ntohs (put->header.size);
1686  putlen = ntohl (put->put_path_length);
1688  gettext_noop ("# P2P PUT requests received"),
1689  1,
1690  GNUNET_NO);
1692  gettext_noop ("# P2P PUT bytes received"),
1693  msize,
1694  GNUNET_NO);
1695  put_path = (const struct GNUNET_PeerIdentity *) &put[1];
1696  payload = &put_path[putlen];
1697  options = ntohl (put->options);
1698  payload_size = msize - (sizeof(struct PeerPutMessage)
1699  + putlen * sizeof(struct GNUNET_PeerIdentity));
1700 
1702  "PUT for `%s' from %s\n",
1703  GNUNET_h2s (&put->key),
1704  GNUNET_i2s (peer->id));
1706  {
1707  char *tmp;
1708  char *pp;
1709 
1710  pp = GNUNET_STRINGS_pp2s (put_path,
1711  putlen);
1714  "R5N PUT %s: %s->%s (%u, %u=>%u, PP: %s)\n",
1715  GNUNET_h2s (&put->key),
1716  GNUNET_i2s (peer->id),
1717  tmp,
1718  ntohl (put->hop_count),
1720  &put->key),
1722  &put->key),
1723  pp);
1724  GNUNET_free (pp);
1725  GNUNET_free (tmp);
1726  }
1727  switch (GNUNET_BLOCK_get_key
1729  ntohl (put->type),
1730  payload,
1731  payload_size,
1732  &test_key))
1733  {
1734  case GNUNET_YES:
1735  if (0 != memcmp (&test_key,
1736  &put->key,
1737  sizeof(struct GNUNET_HashCode)))
1738  {
1739  char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
1740 
1741  GNUNET_break_op (0);
1743  "PUT with key `%s' for block with key %s\n",
1744  put_s,
1745  GNUNET_h2s_full (&test_key));
1746  GNUNET_free (put_s);
1747  return;
1748  }
1749  break;
1750 
1751  case GNUNET_NO:
1752  GNUNET_break_op (0);
1753  return;
1754 
1755  case GNUNET_SYSERR:
1756  /* cannot verify, good luck */
1757  break;
1758  }
1759  if (ntohl (put->type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
1760  {
1762  ntohl (put->type),
1763  NULL, /* query group */
1765  NULL, /* query */
1766  NULL, 0, /* xquery */
1767  payload,
1768  payload_size))
1769  {
1772  break;
1773 
1780  default:
1781  GNUNET_break_op (0);
1782  return;
1783  }
1784  }
1785 
1791  &peer->phash));
1792  {
1793  struct GNUNET_PeerIdentity pp[putlen + 1];
1794 
1795  /* extend 'put path' by sender */
1796  if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
1797  {
1798 #if SANITY_CHECKS
1799  for (unsigned int i = 0; i <= putlen; i++)
1800  {
1801  for (unsigned int j = 0; j < i; j++)
1802  {
1803  GNUNET_break (0 != memcmp (&pp[i],
1804  &pp[j],
1805  sizeof(struct GNUNET_PeerIdentity)));
1806  }
1807  GNUNET_break (0 != memcmp (&pp[i],
1808  peer->id,
1809  sizeof(struct GNUNET_PeerIdentity)));
1810  }
1811 #endif
1812  GNUNET_memcpy (pp,
1813  put_path,
1814  putlen * sizeof(struct GNUNET_PeerIdentity));
1815  pp[putlen] = *peer->id;
1816  putlen++;
1817  }
1818  else
1819  putlen = 0;
1820 
1821  /* give to local clients */
1822  GDS_CLIENTS_handle_reply (exp_time,
1823  &put->key,
1824  0,
1825  NULL,
1826  putlen,
1827  pp,
1828  ntohl (put->type),
1829  payload_size,
1830  payload);
1831  /* store locally */
1832  if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
1833  (GDS_am_closest_peer (&put->key, bf)))
1834  GDS_DATACACHE_handle_put (exp_time,
1835  &put->key,
1836  putlen,
1837  pp,
1838  ntohl (put->type),
1839  payload_size,
1840  payload);
1841  /* route to other peers */
1842  forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type),
1843  options,
1844  ntohl (
1846  exp_time,
1847  ntohl (put->hop_count),
1848  bf,
1849  &put->key,
1850  putlen,
1851  pp,
1852  payload,
1853  payload_size);
1854  /* notify monitoring clients */
1855  GDS_CLIENTS_process_put (options
1856  | ((GNUNET_OK == forwarded)
1858  : 0),
1859  ntohl (put->type),
1860  ntohl (put->hop_count),
1861  ntohl (put->desired_replication_level),
1862  putlen, pp,
1863  exp_time,
1864  &put->key,
1865  payload,
1866  payload_size);
1867  }
1869 }
Block does not match query (invalid result)
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
We should keep track of the route that the message took in the P2P network.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:272
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in &#39;GET&#39; queries.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
Block does not match xquery (valid result, not relevant for the request)
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashCode phash
Hash of id.
Default behavior.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void GDS_CLIENTS_process_put(uint32_t options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
Check if some client is monitoring PUT messages and notify them in that case.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int GNUNET_BLOCK_get_key(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size, struct GNUNET_HashCode *key)
Function called to obtain the key for a block.
Definition: block.c:378
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
Flag given to monitors if this was the last hop for a GET/PUT.
struct GNUNET_HashCode key
The key we are storing under.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
Valid result, but suppressed because it is a duplicate.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
char * GNUNET_STRINGS_pp2s(const struct GNUNET_PeerIdentity *pids, unsigned int num_pids)
Convert a peer path to a human-readable string.
Definition: strings.c:100
enum GNUNET_BLOCK_EvaluationResult GNUNET_BLOCK_evaluate(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate a reply or a request.
Definition: block.c:338
void GDS_DATACACHE_handle_put(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a datum we&#39;ve received from another peer.
int GDS_am_closest_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
Check whether my identity is closer than any known peers.
Last possible valid result.
uint32_t hop_count
Hop count.
A 512-bit hashcode.
GNUNET_DHT_RouteOption
Options for routing.
uint32_t desired_replication_level
Replication level for this message.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
Valid result, and there may be more.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_PUT.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
Entry for a peer in a bucket.
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static unsigned long long payload
How much data are we currently storing in the database?
Specified block type not supported by this plugin.
uint32_t options
Processing options.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
The identity of the host (wraps the signing key of the peer).
uint32_t type
Content type.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
Query format does not match block type (invalid query).
#define GNUNET_log(kind,...)
#define LOG_TRAFFIC(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int log_route_details_stderr
Should routing details be logged to stderr (for debugging)?
Block to store a cadet regex state.
Query is valid, no reply given.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
Each peer along the way should look at &#39;enc&#39; (otherwise only the k-peers closest to the key should lo...
void GDS_CLIENTS_handle_reply(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a reply we&#39;ve received from another peer.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
int GDS_NEIGHBOURS_handle_put(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size)
Perform a PUT operation.
Here is the call graph for this function:

◆ handle_find_peer()

static void handle_find_peer ( const struct GNUNET_PeerIdentity sender,
const struct GNUNET_HashCode key,
struct GNUNET_BLOCK_Group bg 
)
static

We have received a FIND PEER request.

Send matching HELLOs back.

Parameters
sendersender of the FIND PEER request
keypeers close to this key are desired
bggroup for filtering peers

Definition at line 1881 of file gnunet-service-dht_neighbours.c.

References closest_bucket, find_bucket(), GDS_block_context, GDS_HELLO_get(), GDS_my_hello, GDS_NEIGHBOURS_handle_reply(), GDS_stats, gettext_noop, GNUNET_assert, GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, GNUNET_BLOCK_evaluate(), GNUNET_BLOCK_EVALUATION_OK_MORE, GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_break, GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_HELLO_size(), GNUNET_MIN, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_relative_to_absolute(), PeerBucket::head, hello_expiration, PeerInfo::id, k_buckets, my_identity_hash, PeerInfo::next, peer, PeerBucket::peers_size, and PeerInfo::phash.

Referenced by handle_dht_p2p_get().

1884 {
1885  int bucket_idx;
1886  struct PeerBucket *bucket;
1887  struct PeerInfo *peer;
1888  unsigned int choice;
1889  const struct GNUNET_HELLO_Message *hello;
1890  size_t hello_size;
1891 
1892  /* first, check about our own HELLO */
1893  if (NULL != GDS_my_hello)
1894  {
1895  hello_size = GNUNET_HELLO_size ((const struct
1897  GNUNET_break (hello_size >= sizeof(struct GNUNET_MessageHeader));
1901  bg,
1904  NULL, 0,
1905  GDS_my_hello,
1906  hello_size))
1907  {
1912  key,
1913  0,
1914  NULL,
1915  0,
1916  NULL,
1917  GDS_my_hello,
1918  hello_size);
1919  }
1920  else
1921  {
1923  gettext_noop (
1924  "# FIND PEER requests ignored due to Bloomfilter"),
1925  1,
1926  GNUNET_NO);
1927  }
1928  }
1929  else
1930  {
1932  gettext_noop (
1933  "# FIND PEER requests ignored due to lack of HELLO"),
1934  1,
1935  GNUNET_NO);
1936  }
1937 
1938  /* then, also consider sending a random HELLO from the closest bucket */
1939  if (0 == memcmp (&my_identity_hash,
1940  key,
1941  sizeof(struct GNUNET_HashCode)))
1942  bucket_idx = closest_bucket;
1943  else
1944  bucket_idx = GNUNET_MIN ((int) closest_bucket,
1945  find_bucket (key));
1946  if (bucket_idx < 0)
1947  return;
1948  bucket = &k_buckets[bucket_idx];
1949  if (bucket->peers_size == 0)
1950  return;
1952  bucket->peers_size);
1953  peer = bucket->head;
1954  while (choice > 0)
1955  {
1956  GNUNET_assert (NULL != peer);
1957  peer = peer->next;
1958  choice--;
1959  }
1960  choice = bucket->peers_size;
1961  do
1962  {
1963  peer = peer->next;
1964  if (0 == choice--)
1965  return; /* no non-masked peer available */
1966  if (NULL == peer)
1967  peer = bucket->head;
1968  hello = GDS_HELLO_get (peer->id);
1969  }
1970  while ((NULL == hello) ||
1974  bg,
1976  &peer->phash,
1977  NULL, 0,
1978  hello,
1979  (hello_size = GNUNET_HELLO_size (hello)))));
1984  key,
1985  0,
1986  NULL,
1987  0,
1988  NULL,
1989  hello,
1990  hello_size);
1991 }
static unsigned int closest_bucket
The lowest currently used bucket, initially 0 (for 0-bits matching bucket).
struct GNUNET_MessageHeader * GDS_my_hello
Our HELLO.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
A HELLO message is used to exchange information about transports with other peers.
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
struct PeerInfo * next
Next peer entry (DLL)
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct PeerInfo * head
Head of DLL.
static int find_bucket(const struct GNUNET_HashCode *hc)
Find the optimal bucket for this key.
#define GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION
After how long do we expire an address in a HELLO that we just validated? This value is also used for...
unsigned int peers_size
Number of peers in the bucket.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_HashCode phash
Hash of id.
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 GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
enum GNUNET_BLOCK_EvaluationResult GNUNET_BLOCK_evaluate(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate a reply or a request.
Definition: block.c:338
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
Type of a block that contains a HELLO for a peer (for DHT and CADET find-peer operations).
A 512-bit hashcode.
The block is obtained from the local database, skip cryptographic checks.
Peers are grouped into buckets.
Valid result, and there may be more.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Entry for a peer in a bucket.
struct GNUNET_TIME_Relative hello_expiration
Hello address expiration.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
const struct GNUNET_HELLO_Message * GDS_HELLO_get(const struct GNUNET_PeerIdentity *peer)
Obtain a peer&#39;s HELLO if available.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
Header for all communications.
void GDS_NEIGHBOURS_handle_reply(const struct GNUNET_PeerIdentity *target, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
Handle a reply (route to origin).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_local_result()

static void handle_local_result ( void *  cls,
enum GNUNET_BLOCK_Type  type,
struct GNUNET_TIME_Absolute  expiration_time,
const struct GNUNET_HashCode key,
unsigned int  put_path_length,
const struct GNUNET_PeerIdentity put_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity get_path,
const void *  data,
size_t  data_size 
)
static

Handle a result from local datacache for a GET operation.

Parameters
clsthe struct PeerInfo for which this is a reply
typetype of the block
expiration_timewhen does the content expire
keykey for the content
put_path_lengthnumber of entries in put_path
put_pathpeers the original PUT traversed (if tracked)
get_path_lengthnumber of entries in get_path
get_pathpeers this reply has traversed so far (if tracked)
datapayload of the reply
data_sizenumber of bytes in data

Definition at line 2009 of file gnunet-service-dht_neighbours.c.

References GDS_NEIGHBOURS_handle_reply(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_STRINGS_pp2s(), PeerInfo::id, and peer.

Referenced by handle_dht_p2p_get().

2019 {
2020  struct PeerInfo *peer = cls;
2021  char *pp;
2022 
2023  pp = GNUNET_STRINGS_pp2s (put_path,
2024  put_path_length);
2026  "Found local result for %s (PP: %s)\n",
2027  GNUNET_h2s (key),
2028  pp);
2029  GNUNET_free (pp);
2031  type,
2032  expiration_time,
2033  key,
2034  put_path_length, put_path,
2035  get_path_length, get_path,
2036  data, data_size);
2037 }
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
char * GNUNET_STRINGS_pp2s(const struct GNUNET_PeerIdentity *pids, unsigned int num_pids)
Convert a peer path to a human-readable string.
Definition: strings.c:100
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Entry for a peer in a bucket.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
#define GNUNET_log(kind,...)
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
uint32_t data
The data value.
void GDS_NEIGHBOURS_handle_reply(const struct GNUNET_PeerIdentity *target, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
Handle a reply (route to origin).
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_dht_p2p_get()

static int check_dht_p2p_get ( void *  cls,
const struct PeerGetMessage get 
)
static

Check validity of p2p get request.

Parameters
clsclosure with the struct PeerInfo of the sender
getthe message
Returns
GNUNET_OK if the message is well-formed

Definition at line 2048 of file gnunet-service-dht_neighbours.c.

References GNUNET_break_op, GNUNET_OK, and GNUNET_SYSERR.

2050 {
2051  uint32_t xquery_size;
2052  uint16_t msize;
2053 
2054  (void) cls;
2055  msize = ntohs (get->header.size);
2056  xquery_size = ntohl (get->xquery_size);
2057  if (msize < sizeof(struct PeerGetMessage) + xquery_size)
2058  {
2059  GNUNET_break_op (0);
2060  return GNUNET_SYSERR;
2061  }
2062  return GNUNET_OK;
2063 }
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_GET.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
uint32_t xquery_size
Size of the extended query.

◆ handle_dht_p2p_get()

static void handle_dht_p2p_get ( void *  cls,
const struct PeerGetMessage get 
)
static

Core handler for p2p get requests.

Parameters
clsclosure with the struct PeerInfo of the sender
getthe message

Definition at line 2073 of file gnunet-service-dht_neighbours.c.

References DHT_BLOOM_SIZE, GDS_am_closest_peer(), GDS_block_context, GDS_CLIENTS_process_get(), GDS_DATACACHE_handle_get(), GDS_NEIGHBOURS_handle_get(), GDS_ROUTING_add(), GDS_stats, gettext_noop, GNUNET_BLOCK_EO_NONE, GNUNET_BLOCK_evaluate(), GNUNET_BLOCK_EVALUATION_OK_LAST, GNUNET_BLOCK_EVALUATION_REQUEST_VALID, GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED, GNUNET_BLOCK_group_create(), GNUNET_break_op, GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_hash_matching_bits(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_DHT_RO_FIND_PEER, GNUNET_DHT_RO_LAST_HOP, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_strdup, GNUNET_YES, handle_find_peer(), handle_local_result(), PeerInfo::id, log_route_details_stderr, LOG_TRAFFIC, my_identity, my_identity_hash, PeerPutMessage::options, peer, PeerInfo::phash, and PeerPutMessage::type.

2075 {
2076  struct PeerInfo *peer = cls;
2077  uint32_t xquery_size;
2078  size_t reply_bf_size;
2079  uint16_t msize;
2080  enum GNUNET_BLOCK_Type type;
2083  struct GNUNET_BLOCK_Group *bg;
2084  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
2085  const char *xquery;
2086  int forwarded;
2087 
2088  /* parse and validate message */
2089  msize = ntohs (get->header.size);
2090  xquery_size = ntohl (get->xquery_size);
2091  reply_bf_size = msize - (sizeof(struct PeerGetMessage) + xquery_size);
2092  type = ntohl (get->type);
2093  options = ntohl (get->options);
2094  xquery = (const char *) &get[1];
2096  gettext_noop ("# P2P GET requests received"),
2097  1,
2098  GNUNET_NO);
2100  gettext_noop ("# P2P GET bytes received"),
2101  msize,
2102  GNUNET_NO);
2104  {
2105  char *tmp;
2106 
2109  "R5N GET %s: %s->%s (%u, %u=>%u) xq: %.*s\n",
2110  GNUNET_h2s (&get->key),
2111  GNUNET_i2s (peer->id),
2112  tmp,
2113  ntohl (get->hop_count),
2115  &get->key),
2117  &get->key),
2118  ntohl (get->xquery_size),
2119  xquery);
2120  GNUNET_free (tmp);
2121  }
2122  eval
2124  type,
2125  NULL,
2127  &get->key,
2128  xquery,
2129  xquery_size,
2130  NULL,
2131  0);
2133  {
2134  /* request invalid or block type not supported */
2136  return;
2137  }
2143  &peer->phash));
2145  type,
2146  get->bf_mutator,
2147  &xquery[xquery_size],
2148  reply_bf_size,
2149  "filter-size",
2150  reply_bf_size,
2151  NULL);
2153  "GET for %s at %s after %u hops\n",
2154  GNUNET_h2s (&get->key),
2156  (unsigned int) ntohl (get->hop_count));
2157  /* local lookup (this may update the reply_bf) */
2158  if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
2159  (GDS_am_closest_peer (&get->key,
2160  peer_bf)))
2161  {
2162  if ((0 != (options & GNUNET_DHT_RO_FIND_PEER)))
2163  {
2165  gettext_noop (
2166  "# P2P FIND PEER requests processed"),
2167  1,
2168  GNUNET_NO);
2169  handle_find_peer (peer->id,
2170  &get->key,
2171  bg);
2172  }
2173  else
2174  {
2175  eval = GDS_DATACACHE_handle_get (&get->key,
2176  type,
2177  xquery,
2178  xquery_size,
2179  bg,
2181  peer);
2182  }
2183  }
2184  else
2185  {
2187  gettext_noop ("# P2P GET requests ONLY routed"),
2188  1,
2189  GNUNET_NO);
2190  }
2191 
2192  /* remember request for routing replies */
2193  GDS_ROUTING_add (peer->id,
2194  type,
2195  bg, /* bg now owned by routing, but valid at least until end of this function! */
2196  options,
2197  &get->key,
2198  xquery,
2199  xquery_size);
2200 
2201  /* P2P forwarding */
2202  forwarded = GNUNET_NO;
2203  if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST)
2204  forwarded = GDS_NEIGHBOURS_handle_get (type,
2205  options,
2206  ntohl (
2208  ntohl (get->hop_count),
2209  &get->key,
2210  xquery,
2211  xquery_size,
2212  bg,
2213  peer_bf);
2214  GDS_CLIENTS_process_get (options
2215  | (GNUNET_OK == forwarded)
2216  ? GNUNET_DHT_RO_LAST_HOP : 0,
2217  type,
2218  ntohl (get->hop_count),
2219  ntohl (get->desired_replication_level),
2220  0,
2221  NULL,
2222  &get->key);
2223 
2224  /* clean up; note that 'bg' is owned by routing now! */
2226 }
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
uint32_t type
Desired content type.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_GET.
uint32_t hop_count
Hop count.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:272
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in &#39;GET&#39; queries.
static void handle_find_peer(const struct GNUNET_PeerIdentity *sender, const struct GNUNET_HashCode *key, struct GNUNET_BLOCK_Group *bg)
We have received a FIND PEER request.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashCode phash
Hash of id.
uint32_t options
Processing options.
struct GNUNET_HashCode key
The key we are looking for.
Default behavior.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GDS_CLIENTS_process_get(uint32_t options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, const struct GNUNET_HashCode *key)
Check if some client is monitoring GET messages and notify them in that case.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
uint32_t desired_replication_level
Desired replication level for this request.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
Flag given to monitors if this was the last hop for a GET/PUT.
This is a &#39;FIND-PEER&#39; request, so approximate results are fine.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
enum GNUNET_BLOCK_EvaluationResult GNUNET_BLOCK_evaluate(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate a reply or a request.
Definition: block.c:338
int GDS_am_closest_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
Check whether my identity is closer than any known peers.
Last possible valid result.
GNUNET_DHT_RouteOption
Options for routing.
static void handle_local_result(void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
Handle a result from local datacache for a GET operation.
uint32_t bf_mutator
Bloomfilter mutator.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Entry for a peer in a bucket.
GNUNET_BLOCK_EvaluationResult
Possible ways for how a block may relate to a query.
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_group_create(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, uint32_t nonce, const void *raw_data, size_t raw_data_size,...)
Create a new block group.
Definition: block.c:289
uint32_t xquery_size
Size of the extended query.
int GDS_NEIGHBOURS_handle_get(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, uint32_t hop_count, const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, struct GNUNET_CONTAINER_BloomFilter *peer_bf)
Perform a GET operation.
Specified block type not supported by this plugin.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
#define GNUNET_log(kind,...)
Block group data.
#define LOG_TRAFFIC(kind,...)
enum GNUNET_BLOCK_EvaluationResult GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, GDS_DATACACHE_GetCallback gc, void *gc_cls)
Handle a GET request we&#39;ve received from another peer.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
void GDS_ROUTING_add(const struct GNUNET_PeerIdentity *sender, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *bg, enum GNUNET_DHT_RouteOption options, const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size)
Add a new entry to our routing table.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int log_route_details_stderr
Should routing details be logged to stderr (for debugging)?
Query is valid, no reply given.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associcated with a filter in memory, flush to drive if needed (do not free the space o...
Each peer along the way should look at &#39;enc&#39; (otherwise only the k-peers closest to the key should lo...
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:

◆ check_dht_p2p_result()

static int check_dht_p2p_result ( void *  cls,
const struct PeerResultMessage prm 
)
static

Check validity of p2p result message.

Parameters
clsclosure
messagemessage
Returns
GNUNET_YES if the message is well-formed

Definition at line 2237 of file gnunet-service-dht_neighbours.c.

References PeerResultMessage::get_path_length, GNUNET_break_op, GNUNET_MAX_MESSAGE_SIZE, GNUNET_OK, GNUNET_SYSERR, PeerResultMessage::header, PeerPutMessage::put_path_length, PeerResultMessage::put_path_length, and GNUNET_MessageHeader::size.

2239 {
2240  uint32_t get_path_length;
2241  uint32_t put_path_length;
2242  uint16_t msize;
2243 
2244  (void) cls;
2245  msize = ntohs (prm->header.size);
2246  put_path_length = ntohl (prm->put_path_length);
2247  get_path_length = ntohl (prm->get_path_length);
2248  if ((msize <
2249  sizeof(struct PeerResultMessage) + (get_path_length
2250  + put_path_length)
2251  * sizeof(struct GNUNET_PeerIdentity)) ||
2252  (get_path_length >
2253  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
2254  (put_path_length >
2255  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)))
2256  {
2257  GNUNET_break_op (0);
2258  return GNUNET_SYSERR;
2259  }
2260  return GNUNET_OK;
2261 }
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
uint32_t get_path_length
Length of the GET path that follows (if tracked).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
The identity of the host (wraps the signing key of the peer).

◆ process_reply_with_path()

static void process_reply_with_path ( struct GNUNET_TIME_Absolute  expiration_time,
const struct GNUNET_HashCode key,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity get_path,
unsigned int  put_path_length,
const struct GNUNET_PeerIdentity put_path,
enum GNUNET_BLOCK_Type  type,
size_t  data_size,
const void *  data 
)
static

Process a reply, after the get_path has been updated.

Parameters
expiration_timewhen does the reply expire
keykey matching the query
get_path_lengthnumber of entries in get_path
get_pathpath the reply has taken
put_path_lengthnumber of entries in put_path
put_pathpath the PUT has taken
typetype of the block
data_sizenumber of bytes in data
datapayload of the reply

Definition at line 2278 of file gnunet-service-dht_neighbours.c.

References cache_results, GDS_CLIENTS_handle_reply(), GDS_CLIENTS_process_get_resp(), GDS_DATACACHE_handle_put(), GDS_ROUTING_process(), GNUNET_memcpy, and GNUNET_YES.

Referenced by handle_dht_p2p_result().

2287 {
2288  /* forward to local clients */
2289  GDS_CLIENTS_handle_reply (expiration_time,
2290  key,
2291  get_path_length,
2292  get_path,
2293  put_path_length,
2294  put_path,
2295  type,
2296  data_size,
2297  data);
2299  get_path,
2300  get_path_length,
2301  put_path,
2302  put_path_length,
2303  expiration_time,
2304  key,
2305  data,
2306  data_size);
2307  if (GNUNET_YES == cache_results)
2308  {
2309  struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length];
2310 
2311  GNUNET_memcpy (xput_path,
2312  put_path,
2313  put_path_length * sizeof(struct GNUNET_PeerIdentity));
2314  GNUNET_memcpy (&xput_path[put_path_length],
2315  get_path,
2316  get_path_length * sizeof(struct GNUNET_PeerIdentity));
2317 
2318  GDS_DATACACHE_handle_put (expiration_time,
2319  key,
2320  get_path_length + put_path_length,
2321  xput_path,
2322  type,
2323  data_size,
2324  data);
2325  }
2326  /* forward to other peers */
2328  expiration_time,
2329  key,
2330  put_path_length,
2331  put_path,
2332  get_path_length,
2333  get_path,
2334  data,
2335  data_size);
2336 }
static int cache_results
Do we cache all results that we are routing in the local datacache?
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void GDS_DATACACHE_handle_put(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a datum we&#39;ve received from another peer.
void GDS_CLIENTS_process_get_resp(enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
Check if some client is monitoring GET RESP messages and notify them in that case.
void GDS_ROUTING_process(enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
Handle a reply (route to origin).
The identity of the host (wraps the signing key of the peer).
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:77
uint32_t data
The data value.
void GDS_CLIENTS_handle_reply(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a reply we&#39;ve received from another peer.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_dht_p2p_result()

static void handle_dht_p2p_result ( void *  cls,
const struct PeerResultMessage prm 
)
static

Core handler for p2p result messages.

Parameters
clsclosure
messagemessage

Definition at line 2346 of file gnunet-service-dht_neighbours.c.

References data, data_size, disable_try_connect, PeerResultMessage::expiration_time, GDS_stats, PeerResultMessage::get_path_length, gettext_noop, GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_HELLO_get_id(), GNUNET_i2s(), GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_strdup, GNUNET_STRINGS_pp2s(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, h, PeerResultMessage::header, PeerInfo::id, PeerResultMessage::key, log_route_details_stderr, LOG_TRAFFIC, my_identity, peer, process_reply_with_path(), PeerPutMessage::put_path_length, PeerResultMessage::put_path_length, GNUNET_MessageHeader::size, try_connect(), PeerPutMessage::type, and PeerResultMessage::type.

2348 {
2349  struct PeerInfo *peer = cls;
2350  const struct GNUNET_PeerIdentity *put_path;
2351  const struct GNUNET_PeerIdentity *get_path;
2352  const void *data;
2353  uint32_t get_path_length;
2354  uint32_t put_path_length;
2355  uint16_t msize;
2356  size_t data_size;
2357  enum GNUNET_BLOCK_Type type;
2358  struct GNUNET_TIME_Absolute exp_time;
2359 
2360  /* parse and validate message */
2361  exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time);
2362  if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us)
2363  {
2365  gettext_noop ("# Expired results discarded"),
2366  1,
2367  GNUNET_NO);
2368  return;
2369  }
2370  msize = ntohs (prm->header.size);
2371  put_path_length = ntohl (prm->put_path_length);
2372  get_path_length = ntohl (prm->get_path_length);
2373  put_path = (const struct GNUNET_PeerIdentity *) &prm[1];
2374  get_path = &put_path[put_path_length];
2375  type = ntohl (prm->type);
2376  data = (const void *) &get_path[get_path_length];
2377  data_size = msize - (sizeof(struct PeerResultMessage)
2378  + (get_path_length
2379  + put_path_length) * sizeof(struct
2382  gettext_noop ("# P2P RESULTS received"),
2383  1,
2384  GNUNET_NO);
2386  gettext_noop ("# P2P RESULT bytes received"),
2387  msize,
2388  GNUNET_NO);
2390  {
2391  char *tmp;
2392  char *pp;
2393  char *gp;
2394 
2395  gp = GNUNET_STRINGS_pp2s (get_path,
2396  get_path_length);
2397  pp = GNUNET_STRINGS_pp2s (put_path,
2398  put_path_length);
2401  "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n",
2402  GNUNET_h2s (&prm->key),
2403  GNUNET_i2s (peer->id),
2404  tmp,
2405  gp,
2406  pp);
2407  GNUNET_free (gp);
2408  GNUNET_free (pp);
2409  GNUNET_free (tmp);
2410  }
2411  /* if we got a HELLO, consider it for our own routing table */
2412  if (GNUNET_BLOCK_TYPE_DHT_HELLO == type)
2413  {
2414  const struct GNUNET_MessageHeader *h;
2415  struct GNUNET_PeerIdentity pid;
2416 
2417  /* Should be a HELLO, validate and consider using it! */
2418  if (data_size < sizeof(struct GNUNET_HELLO_Message))
2419  {
2420  GNUNET_break_op (0);
2421  return;
2422  }
2423  h = data;
2424  if (data_size != ntohs (h->size))
2425  {
2426  GNUNET_break_op (0);
2427  return;
2428  }
2429  if (GNUNET_OK !=
2430  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) h,
2431  &pid))
2432  {
2433  GNUNET_break_op (0);
2434  return;
2435  }
2436  if ((GNUNET_YES != disable_try_connect) &&
2437  (0 != memcmp (&my_identity,
2438  &pid,
2439  sizeof(struct GNUNET_PeerIdentity))))
2440  try_connect (&pid,
2441  h);
2442  }
2443 
2444  /* First, check if 'peer' is already on the path, and if
2445  so, truncate it instead of expanding. */
2446  for (unsigned int i = 0; i <= get_path_length; i++)
2447  if (0 == memcmp (&get_path[i],
2448  peer->id,
2449  sizeof(struct GNUNET_PeerIdentity)))
2450  {
2451  process_reply_with_path (exp_time,
2452  &prm->key,
2453  i,
2454  get_path,
2455  put_path_length,
2456  put_path,
2457  type,
2458  data_size,
2459  data);
2460  return;
2461  }
2462 
2463  /* Need to append 'peer' to 'get_path' (normal case) */
2464  {
2465  struct GNUNET_PeerIdentity xget_path[get_path_length + 1];
2466 
2467  GNUNET_memcpy (xget_path,
2468  get_path,
2469  get_path_length * sizeof(struct GNUNET_PeerIdentity));
2470  xget_path[get_path_length] = *peer->id;
2471 
2472  process_reply_with_path (exp_time,
2473  &prm->key,
2474  get_path_length + 1,
2475  xget_path,
2476  put_path_length,
2477  put_path,
2478  type,
2479  data_size,
2480  data);
2481  }
2482 }
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:671
uint32_t type
Content type.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
A HELLO message is used to exchange information about transports with other peers.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint32_t get_path_length
Length of the GET path that follows (if tracked).
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int disable_try_connect
Option for testing that disables the &#39;connect&#39; function of the DHT.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
char * GNUNET_STRINGS_pp2s(const struct GNUNET_PeerIdentity *pids, unsigned int num_pids)
Convert a peer path to a human-readable string.
Definition: strings.c:100
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT.
Type of a block that contains a HELLO for a peer (for DHT and CADET find-peer operations).
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Entry for a peer in a bucket.
static void process_reply_with_path(struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Process a reply, after the get_path has been updated.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
The identity of the host (wraps the signing key of the peer).
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?
static void try_connect(const struct GNUNET_PeerIdentity *pid, const struct GNUNET_MessageHeader *h)
Consider if we want to connect to a given peer, and if so let ATS know.
#define LOG_TRAFFIC(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int log_route_details_stderr
Should routing details be logged to stderr (for debugging)?
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
uint32_t data
The data value.
struct GNUNET_HashCode key
The key of the corresponding GET request.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:

◆ GDS_NEIGHBOURS_init()

int GDS_NEIGHBOURS_init ( void  )

Initialize neighbours subsystem.

Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 2491 of file gnunet-service-dht_neighbours.c.

References bucket_size, cache_results, core_init(), disable_try_connect, GDS_cfg, getenv(), GNUNET_ATS_connectivity_init(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_CORE_connect(), GNUNET_MESSAGE_TYPE_DHT_P2P_GET, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, handle_core_connect(), handle_core_disconnect(), and log_route_details_stderr.

Referenced by run().

2492 {
2493  struct GNUNET_MQ_MessageHandler core_handlers[] = {
2494  GNUNET_MQ_hd_var_size (dht_p2p_get,
2496  struct PeerGetMessage,
2497  NULL),
2498  GNUNET_MQ_hd_var_size (dht_p2p_put,
2500  struct PeerPutMessage,
2501  NULL),
2502  GNUNET_MQ_hd_var_size (dht_p2p_result,
2504  struct PeerResultMessage,
2505  NULL),
2507  };
2508  unsigned long long temp_config_num;
2509 
2512  "DHT",
2513  "DISABLE_TRY_CONNECT");
2514  if (GNUNET_OK ==
2516  "DHT",
2517  "bucket_size",
2518  &temp_config_num))
2519  bucket_size = (unsigned int) temp_config_num;
2522  "DHT",
2523  "CACHE_RESULTS");
2524 
2526  (NULL != getenv ("GNUNET_DHT_ROUTE_DEBUG")) ? GNUNET_YES : GNUNET_NO;
2529  NULL,
2530  &core_init,
2533  core_handlers);
2534  if (NULL == core_api)
2535  return GNUNET_SYSERR;
2537  GNUNET_YES);
2539  GNUNET_NO);
2540  return GNUNET_OK;
2541 }
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static int cache_results
Do we cache all results that we are routing in the local datacache?
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void core_init(void *cls, const struct GNUNET_PeerIdentity *identity)
To be called on core init/fail.
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).
static int disable_try_connect
Option for testing that disables the &#39;connect&#39; function of the DHT.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
Message handler for a specific message type.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_GET
Peer tries to find data in DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Connect to the core service.
Definition: core_api.c:692
char * getenv()
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
static struct GNUNET_CORE_Handle * core_api
Handle to CORE.
struct GNUNET_ATS_ConnectivityHandle * GNUNET_ATS_connectivity_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the ATS connectivity suggestion client handle.
static struct GNUNET_ATS_ConnectivityHandle * ats_ch
Handle to ATS connectivity.
static void handle_core_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
static unsigned int bucket_size
Maximum size for each bucket.
static struct GNUNET_CONTAINER_MultiPeerMap * all_desired_peers
Hash map of all peers we would like to be connected to.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int log_route_details_stderr
Should routing details be logged to stderr (for debugging)?
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
Configuration we use.
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
#define GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
Peer is storing data in DHT.
static void * handle_core_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a peer connects.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
Data is returned to peer from DHT.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_done()

void GDS_NEIGHBOURS_done ( void  )

Shutdown neighbours subsystem.

Definition at line 2548 of file gnunet-service-dht_neighbours.c.

References free_connect_info(), GNUNET_assert, GNUNET_ATS_connectivity_done(), GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CONTAINER_multipeermap_size(), and GNUNET_CORE_disconnect().

Referenced by shutdown_task().

2549 {
2550  if (NULL == core_api)
2551  return;
2553  core_api = NULL;
2554  GNUNET_assert (0 ==
2557  all_connected_peers = NULL;
2560  NULL);
2562  all_desired_peers = NULL;
2564  ats_ch = NULL;
2565  GNUNET_assert (NULL == find_peer_task);
2566 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_Task * find_peer_task
Task that sends FIND PEER requests.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
static int free_connect_info(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Function called for all entries in all_desired_peers to clean up.
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:730
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
static struct GNUNET_CORE_Handle * core_api
Handle to CORE.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static struct GNUNET_ATS_ConnectivityHandle * ats_ch
Handle to ATS connectivity.
static struct GNUNET_CONTAINER_MultiPeerMap * all_desired_peers
Hash map of all peers we would like to be connected to.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
void GNUNET_ATS_connectivity_done(struct GNUNET_ATS_ConnectivityHandle *ch)
Client is done with ATS connectivity management, release resources.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_get_id()

struct GNUNET_PeerIdentity* GDS_NEIGHBOURS_get_id ( void  )

Get the ID of the local node.

Returns
identity of the local node

Definition at line 2575 of file gnunet-service-dht_neighbours.c.

References my_identity.

Referenced by handle_dht_local_get(), and handle_dht_local_put().

2576 {
2577  return &my_identity;
2578 }
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
Here is the caller graph for this function:

Variable Documentation

◆ hello_expiration

struct GNUNET_TIME_Relative hello_expiration

Hello address expiration.

Definition at line 55 of file gnunet-service-dht.c.

Referenced by handle_find_peer().

◆ cache_results

int cache_results
static

Do we cache all results that we are routing in the local datacache?

Definition at line 347 of file gnunet-service-dht_neighbours.c.

Referenced by GDS_NEIGHBOURS_init(), and process_reply_with_path().

◆ log_route_details_stderr

int log_route_details_stderr
static

Should routing details be logged to stderr (for debugging)?

Definition at line 352 of file gnunet-service-dht_neighbours.c.

Referenced by GDS_NEIGHBOURS_init(), handle_dht_p2p_get(), handle_dht_p2p_put(), and handle_dht_p2p_result().

◆ closest_bucket

unsigned int closest_bucket
static

The lowest currently used bucket, initially 0 (for 0-bits matching bucket).

Definition at line 357 of file gnunet-service-dht_neighbours.c.

Referenced by handle_core_connect(), handle_core_disconnect(), handle_find_peer(), and select_peer().

◆ newly_found_peers

unsigned int newly_found_peers
static

How many peers have we added since we sent out our last find peer request?

Definition at line 363 of file gnunet-service-dht_neighbours.c.

Referenced by handle_core_connect(), and send_find_peer_message().

◆ disable_try_connect

int disable_try_connect
static

Option for testing that disables the 'connect' function of the DHT.

Definition at line 368 of file gnunet-service-dht_neighbours.c.

Referenced by GDS_NEIGHBOURS_init(), handle_core_connect(), handle_core_disconnect(), and handle_dht_p2p_result().

◆ k_buckets

struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
static

The buckets.

Array of size MAX_BUCKETS. Offset 0 means 0 bits matching.

Definition at line 373 of file gnunet-service-dht_neighbours.c.

Referenced by GDS_am_closest_peer(), handle_core_connect(), handle_core_disconnect(), handle_find_peer(), select_peer(), and try_connect().

◆ all_connected_peers

struct GNUNET_CONTAINER_MultiPeerMap* all_connected_peers
static

Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.

Values are of type struct PeerInfo.

Definition at line 379 of file gnunet-service-dht_neighbours.c.

◆ all_desired_peers

struct GNUNET_CONTAINER_MultiPeerMap* all_desired_peers
static

Hash map of all peers we would like to be connected to.

Values are of type struct ConnectInfo.

Definition at line 385 of file gnunet-service-dht_neighbours.c.

◆ bucket_size

unsigned int bucket_size = 8
static

◆ find_peer_task

struct GNUNET_SCHEDULER_Task* find_peer_task
static

Task that sends FIND PEER requests.

Definition at line 395 of file gnunet-service-dht_neighbours.c.

◆ my_identity

struct GNUNET_PeerIdentity my_identity
static

◆ my_identity_hash

struct GNUNET_HashCode my_identity_hash

◆ core_api

struct GNUNET_CORE_Handle* core_api
static

Handle to CORE.

Definition at line 410 of file gnunet-service-dht_neighbours.c.

◆ ats_ch

struct GNUNET_ATS_ConnectivityHandle* ats_ch
static

Handle to ATS connectivity.

Definition at line 415 of file gnunet-service-dht_neighbours.c.