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 uint64_t get_distance (const struct GNUNET_HashCode *target, const struct GNUNET_HashCode *have, unsigned int bucket)
 Compute the distance between have and target as a 64-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.

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

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

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

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

◆ 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:311

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

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

◆ DHT_MAXIMUM_FIND_PEER_INTERVAL

#define DHT_MAXIMUM_FIND_PEER_INTERVAL
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.

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

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

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

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 }
#define MAX_BUCKETS
How many buckets will we allow total.
struct GNUNET_HashCode my_identity_hash
Hash of the identity of this peer.
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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:189
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.

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().

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.

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

References ConnectInfo::oh.

Referenced by try_connect().

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.

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 }
static char * value
Value of the record to add/remove.
static struct GNUNET_CONTAINER_MultiPeerMap * all_desired_peers
Hash map of all peers we would like to be connected to.
@ GNUNET_YES
Definition: gnunet_common.h:97
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_free(ptr)
Wrapper around free.
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.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.

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

Referenced by GDS_NEIGHBOURS_done(), and try_connect().

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.

502 {
503  int bucket;
504  struct GNUNET_HashCode pid_hash;
505  struct ConnectInfo *ci;
506  uint32_t strength;
507 
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 GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
Configuration we use.
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.
static struct GNUNET_ATS_ConnectivityHandle * ats_ch
Handle to ATS connectivity.
static int find_bucket(const struct GNUNET_HashCode *hc)
Find the optimal bucket for this key.
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
static unsigned int bucket_size
Maximum size for each bucket.
static void offer_hello_done(void *cls)
Function called when GNUNET_TRANSPORT_offer_hello() is done.
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
@ GNUNET_OK
Definition: gnunet_common.h:95
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.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
int GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL).
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct 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.
uint32_t strength
How much would we like to connect to this peer?
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
unsigned int peers_size
Number of peers in the bucket.

References all_connected_peers, all_desired_peers, ats_ch, 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, h, k_buckets, offer_hello_done(), ConnectInfo::oh, PeerBucket::peers_size, pid, ConnectInfo::sh, and ConnectInfo::strength.

Referenced by handle_dht_p2p_result(), and update_desire_strength().

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.

582 {
583  (void) cls;
584  (void) value;
585  try_connect (pid,
586  NULL);
587  return GNUNET_YES;
588 }
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.

References GNUNET_YES, pid, try_connect(), and value.

Referenced by update_connect_preferences().

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.

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.

References all_desired_peers, GNUNET_CONTAINER_multipeermap_iterate(), and update_desire_strength().

Referenced by handle_core_connect(), and handle_core_disconnect().

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.

619 {
620  struct GNUNET_BLOCK_Group *bg = cls;
621  struct GNUNET_HashCode key_hash;
622 
623  (void) cls;
624  (void) value;
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 }
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_log(kind,...)
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:410
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
Block group data.

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

Referenced by send_find_peer_message().

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.

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 }
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
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...
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.
static unsigned int newly_found_peers
How many peers have we added since we sent out our last find peer request?
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 duplica...
#define FIND_PEER_REPLICATION_LEVEL
Desired replication level for FIND PEER requests.
#define DHT_MINIMUM_FIND_PEER_INTERVAL
How long at least to wait before sending another find peer request.
static struct GNUNET_SCHEDULER_Task * find_peer_task
Task that sends FIND PEER requests.
#define DHT_MAXIMUM_FIND_PEER_INTERVAL
How long at most to wait before sending another find peer request.
@ GNUNET_NO
Definition: gnunet_common.h:94
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:206
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:290
@ GNUNET_BLOCK_TYPE_DHT_HELLO
Type of a block that contains a HELLO for a peer (for DHT and CADET find-peer operations).
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in 'GET' queries.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
@ GNUNET_DHT_RO_RECORD_ROUTE
We should keep track of the route that the message took in the P2P network.
@ GNUNET_DHT_RO_FIND_PEER
This is a 'FIND-PEER' request, so approximate results are fine.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
Time for relative time used by GNUnet, in microseconds.

References add_known_to_bloom(), all_connected_peers, bucket_size, DHT_BLOOM_SIZE, DHT_MAXIMUM_FIND_PEER_INTERVAL, DHT_MINIMUM_FIND_PEER_INTERVAL, FIND_PEER_REPLICATION_LEVEL, find_peer_task, 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().

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.

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;
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));
753  k_buckets[pi->peer_bucket].tail,
754  pi);
755  k_buckets[pi->peer_bucket].peers_size++;
757  (unsigned int) pi->peer_bucket);
760  pi->id,
761  pi,
763  if ((pi->peer_bucket > 0) &&
764  (k_buckets[pi->peer_bucket].peers_size <= bucket_size))
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 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
static int disable_try_connect
Option for testing that disables the 'connect' function of the DHT.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static void update_connect_preferences()
Update our preferences for connectivity as given to ATS.
static unsigned int closest_bucket
The lowest currently used bucket, initially 0 (for 0-bits matching bucket).
#define GNUNET_MAX(a, b)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
struct GNUNET_MQ_Handle * mq
Connection to the service.
Definition: peerinfo_api.c:94
struct PeerInfo * head
Head of DLL.
struct PeerInfo * tail
Tail of DLL.
Entry for a peer in a bucket.

References all_connected_peers, bucket_size, closest_bucket, disable_try_connect, find_bucket(), find_peer_task, 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, k_buckets, MAX_BUCKETS, mq, GNUNET_PEERINFO_Handle::mq, my_identity, newly_found_peers, peer, PeerBucket::peers_size, pi, send_find_peer_message(), PeerBucket::tail, and update_connect_preferences().

Referenced by GDS_NEIGHBOURS_init().

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.

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.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
int peer_bucket
Which bucket is this peer in?

References all_connected_peers, bucket_size, closest_bucket, disable_try_connect, find_peer_task, 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, peer, PeerInfo::peer_bucket, PeerBucket::peers_size, PeerBucket::tail, and update_connect_preferences().

Referenced by GDS_NEIGHBOURS_init().

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.

842 {
843  uint32_t random_value;
844  uint32_t forward_count;
845  float target_value;
846 
847  if (0 == target_replication)
848  target_replication = 1; /* 0 is verboten */
849  if (target_replication > MAXIMUM_REPLICATION_LEVEL)
850  target_replication = MAXIMUM_REPLICATION_LEVEL;
851  if (hop_count > GDS_NSE_get () * 4.0)
852  {
853  /* forcefully terminate */
855  gettext_noop ("# requests TTL-dropped"),
856  1, GNUNET_NO);
857  return 0;
858  }
859  if (hop_count > GDS_NSE_get () * 2.0)
860  {
861  /* Once we have reached our ideal number of hops, only forward to 1 peer */
862  return 1;
863  }
864  /* bound by system-wide maximum */
865  target_replication =
866  GNUNET_MIN (MAXIMUM_REPLICATION_LEVEL, target_replication);
867  target_value =
868  1 + (target_replication - 1.0) / (GDS_NSE_get ()
869  + ((float) (target_replication - 1.0)
870  * hop_count));
871 
872 
873  /* Set forward count to floor of target_value */
874  forward_count = (uint32_t) target_value;
875  /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */
876  target_value = target_value - forward_count;
877  random_value =
879  if (random_value < (target_value * UINT32_MAX))
880  forward_count++;
881  return GNUNET_MIN (forward_count,
883 }
#define MAXIMUM_REPLICATION_LEVEL
Maximum allowed replication level for all requests.
double GDS_NSE_get()
Return the log of the current network size estimate.
#define GNUNET_MIN(a, b)

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

Referenced by get_target_peers().

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

◆ get_distance()

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

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

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

Parameters
target
have
bucketup to which offset are target and have identical and thus those bits should not be considered
Returns
0 if have==target, otherwise a number that is larger as the distance between the two hash codes increases

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

902 {
903  uint64_t lsb = 0;
904 
905  for (unsigned int i = bucket + 1;
906  (i < sizeof(struct GNUNET_HashCode) * 8) &&
907  (i < bucket + 1 + 64);
908  i++)
909  {
910  if (GNUNET_CRYPTO_hash_get_bit_rtl (target, i) !=
912  lsb |= (1LLU << (bucket + 64 - i)); /* first bit set will be 1,
913  * last bit set will be 63 -- if
914  * i does not reach 512 first... */
915  }
916  return lsb;
917 }
int GNUNET_CRYPTO_hash_get_bit_rtl(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:180

References GNUNET_CRYPTO_hash_get_bit_rtl().

Referenced by select_peer().

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 931 of file gnunet-service-dht_neighbours.c.

933 {
934  int bits;
935  int other_bits;
936  int bucket_num;
937  struct PeerInfo *pos;
938 
939  if (0 == GNUNET_memcmp (&my_identity_hash,
940  key))
941  return GNUNET_YES;
942  bucket_num = find_bucket (key);
943  GNUNET_assert (bucket_num >= 0);
945  key);
946  pos = k_buckets[bucket_num].head;
947  while (NULL != pos)
948  {
949  if ((NULL != bloom) &&
950  (GNUNET_YES ==
952  &pos->phash)))
953  {
954  pos = pos->next;
955  continue; /* Skip already checked entries */
956  }
957  other_bits = GNUNET_CRYPTO_hash_matching_bits (&pos->phash,
958  key);
959  if (other_bits > bits)
960  return GNUNET_NO;
961  if (other_bits == bits) /* We match the same number of bits */
962  return GNUNET_YES;
963  pos = pos->next;
964  }
965  /* No peers closer, we are the closest! */
966  return GNUNET_YES;
967 }
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
struct PeerInfo * next
Next peer entry (DLL)
struct GNUNET_HashCode phash
Hash of id.

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, key, my_identity_hash, PeerInfo::next, and PeerInfo::phash.

Referenced by handle_dht_p2p_get(), and handle_dht_p2p_put().

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 988 of file gnunet-service-dht_neighbours.c.

991 {
992  unsigned int bc;
993  unsigned int count;
994  unsigned int selected;
995  struct PeerInfo *pos;
996  struct PeerInfo *chosen;
997 
998  if (hops >= GDS_NSE_get ())
999  {
1000  /* greedy selection (closest peer that is not in bloomfilter) */
1001  unsigned int best_bucket = 0;
1002  uint64_t best_in_bucket = UINT64_MAX;
1003 
1004  chosen = NULL;
1005  for (bc = 0; bc <= closest_bucket; bc++)
1006  {
1007  count = 0;
1008  for (pos = k_buckets[bc].head;
1009  (pos != NULL) &&
1010  (count < bucket_size);
1011  pos = pos->next)
1012  {
1013  unsigned int bucket;
1014  uint64_t dist;
1015 
1017  &pos->phash);
1018  dist = get_distance (key,
1019  &pos->phash,
1020  bucket);
1021  if (bucket < best_bucket)
1022  continue;
1023  if (dist > best_in_bucket)
1024  continue;
1025  best_bucket = bucket;
1026  best_in_bucket = dist;
1027  if ( (NULL == bloom) ||
1028  (GNUNET_NO ==
1030  &pos->phash)) )
1031  {
1032  chosen = pos;
1033  }
1034  else
1035  {
1037  "Excluded peer `%s' due to BF match in greedy routing for %s\n",
1038  GNUNET_i2s (pos->id),
1039  GNUNET_h2s (key));
1041  gettext_noop (
1042  "# Peers excluded from routing due to Bloomfilter"),
1043  1,
1044  GNUNET_NO);
1045  chosen = NULL;
1046  }
1047  count++;
1048  }
1049  }
1050  if (NULL == chosen)
1052  gettext_noop ("# Peer selection failed"),
1053  1,
1054  GNUNET_NO);
1055  else
1057  "Selected peer `%s' in greedy routing for %s\n",
1058  GNUNET_i2s (chosen->id),
1059  GNUNET_h2s (key));
1060  return chosen;
1061  }
1062 
1063  /* select "random" peer */
1064  /* count number of peers that are available and not filtered */
1065  count = 0;
1066  for (bc = 0; bc <= closest_bucket; bc++)
1067  {
1068  pos = k_buckets[bc].head;
1069  while ((NULL != pos) && (count < bucket_size))
1070  {
1071  if ((NULL != bloom) &&
1072  (GNUNET_YES ==
1074  &pos->phash)))
1075  {
1077  gettext_noop
1078  (
1079  "# Peers excluded from routing due to Bloomfilter"),
1080  1, GNUNET_NO);
1082  "Excluded peer `%s' due to BF match in random routing for %s\n",
1083  GNUNET_i2s (pos->id),
1084  GNUNET_h2s (key));
1085  pos = pos->next;
1086  continue; /* Ignore bloomfiltered peers */
1087  }
1088  count++;
1089  pos = pos->next;
1090  }
1091  }
1092  if (0 == count) /* No peers to select from! */
1093  {
1095  gettext_noop ("# Peer selection failed"), 1,
1096  GNUNET_NO);
1097  return NULL;
1098  }
1099  /* Now actually choose a peer */
1101  count);
1102  count = 0;
1103  for (bc = 0; bc <= closest_bucket; bc++)
1104  {
1105  for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size));
1106  pos = pos->next)
1107  {
1108  if ((bloom != NULL) &&
1109  (GNUNET_YES ==
1111  &pos->phash)))
1112  {
1113  continue; /* Ignore bloomfiltered peers */
1114  }
1115  if (0 == selected--)
1116  {
1118  "Selected peer `%s' in random routing for %s\n",
1119  GNUNET_i2s (pos->id),
1120  GNUNET_h2s (key));
1121  return pos;
1122  }
1123  }
1124  }
1125  GNUNET_break (0);
1126  return NULL;
1127 }
static struct PendingResolutions * head
Head of list of pending resolution requests.
Definition: gnunet-ats.c:230
static uint64_t get_distance(const struct GNUNET_HashCode *target, const struct GNUNET_HashCode *have, unsigned int bucket)
Compute the distance between have and target as a 64-bit value.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
const struct GNUNET_PeerIdentity * id
What is the identity of the peer?

References bucket_size, closest_bucket, GDS_NSE_get(), GDS_stats, get_distance(), gettext_noop, GNUNET_break, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_hash_matching_bits(), 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, key, PeerInfo::next, and PeerInfo::phash.

Referenced by get_target_peers().

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 1144 of file gnunet-service-dht_neighbours.c.

1149 {
1150  unsigned int ret;
1151  unsigned int off;
1152  struct PeerInfo **rtargets;
1153  struct PeerInfo *nxt;
1154 
1155  GNUNET_assert (NULL != bloom);
1156  ret = get_forward_count (hop_count,
1157  target_replication);
1158  if (0 == ret)
1159  {
1160  *targets = NULL;
1161  return 0;
1162  }
1163  rtargets = GNUNET_new_array (ret,
1164  struct PeerInfo *);
1165  for (off = 0; off < ret; off++)
1166  {
1167  nxt = select_peer (key,
1168  bloom,
1169  hop_count);
1170  if (NULL == nxt)
1171  break;
1172  rtargets[off] = nxt;
1175  &nxt->phash));
1177  &nxt->phash);
1178  }
1180  "Selected %u/%u peers at hop %u for %s (target was %u)\n",
1181  off,
1183  (unsigned int) hop_count,
1184  GNUNET_h2s (key),
1185  ret);
1186  if (0 == off)
1187  {
1188  GNUNET_free (rtargets);
1189  *targets = NULL;
1190  return 0;
1191  }
1192  *targets = rtargets;
1194  "Forwarding query `%s' to %u peers (goal was %u peers)\n",
1195  GNUNET_h2s (key),
1196  off,
1197  ret);
1198  return off;
1199 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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...
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...
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.

References all_connected_peers, 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, key, PeerInfo::phash, ret, and select_peer().

Referenced by GDS_NEIGHBOURS_handle_get(), and GDS_NEIGHBOURS_handle_put().

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 1223 of file gnunet-service-dht_neighbours.c.

1234 {
1235  unsigned int target_count;
1236  unsigned int i;
1237  struct PeerInfo **targets;
1238  struct PeerInfo *target;
1239  size_t msize;
1240  struct GNUNET_MQ_Envelope *env;
1241  struct PeerPutMessage *ppm;
1242  struct GNUNET_PeerIdentity *pp;
1243  unsigned int skip_count;
1244 
1245  GNUNET_assert (NULL != bf);
1247  "Adding myself (%s) to PUT bloomfilter for %s\n",
1249  GNUNET_h2s (key));
1251  &my_identity_hash);
1253  gettext_noop ("# PUT requests routed"),
1254  1,
1255  GNUNET_NO);
1256  target_count
1257  = get_target_peers (key,
1258  bf,
1259  hop_count,
1260  desired_replication_level,
1261  &targets);
1262  if (0 == target_count)
1263  {
1265  "Routing PUT for %s terminates after %u hops at %s\n",
1266  GNUNET_h2s (key),
1267  (unsigned int) hop_count,
1268  GNUNET_i2s (&my_identity));
1269  return GNUNET_NO;
1270  }
1271  msize = put_path_length * sizeof(struct GNUNET_PeerIdentity) + data_size;
1272  if (msize + sizeof(struct PeerPutMessage)
1274  {
1275  put_path_length = 0;
1276  msize = data_size;
1277  }
1278  if (msize + sizeof(struct PeerPutMessage)
1280  {
1281  GNUNET_break (0);
1282  GNUNET_free (targets);
1283  return GNUNET_NO;
1284  }
1286  gettext_noop (
1287  "# PUT messages queued for transmission"),
1288  target_count,
1289  GNUNET_NO);
1290  skip_count = 0;
1291  for (i = 0; i < target_count; i++)
1292  {
1293  target = targets[i];
1295  {
1296  /* skip */
1298  gettext_noop (
1299  "# P2P messages dropped due to full queue"),
1300  1,
1301  GNUNET_NO);
1302  skip_count++;
1303  continue;
1304  }
1306  "Routing PUT for %s after %u hops to %s\n",
1307  GNUNET_h2s (key),
1308  (unsigned int) hop_count,
1309  GNUNET_i2s (target->id));
1310  env = GNUNET_MQ_msg_extra (ppm,
1311  msize,
1313  ppm->options = htonl (options);
1314  ppm->type = htonl (type);
1315  ppm->hop_count = htonl (hop_count + 1);
1316  ppm->desired_replication_level = htonl (desired_replication_level);
1317  ppm->put_path_length = htonl (put_path_length);
1318  ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1321  &target->phash));
1324  ppm->bloomfilter,
1325  DHT_BLOOM_SIZE));
1326  ppm->key = *key;
1327  pp = (struct GNUNET_PeerIdentity *) &ppm[1];
1328  GNUNET_memcpy (pp,
1329  put_path,
1330  sizeof(struct GNUNET_PeerIdentity) * put_path_length);
1331  GNUNET_memcpy (&pp[put_path_length],
1332  data,
1333  data_size);
1334  GNUNET_MQ_send (target->mq,
1335  env);
1336  }
1337  GNUNET_free (targets);
1338  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1339 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t data
The data value.
#define MAXIMUM_PENDING_PER_PEER
Maximum allowed number of pending messages per 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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE
What is the maximum size for encrypted messages? Note that this number imposes a clear limit on the m...
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:337
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MESSAGE_TYPE_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:464
struct GNUNET_MQ_Handle * mq
Handle for sending messages to this peer.
uint32_t options
Processing options.
uint32_t type
Content type.
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
struct GNUNET_HashCode key
The key we are storing under.
uint32_t desired_replication_level
Replication level for this message.
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
uint32_t hop_count
Hop count.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References PeerPutMessage::bloomfilter, data, 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, key, PeerPutMessage::key, MAXIMUM_PENDING_PER_PEER, PeerInfo::mq, my_identity, my_identity_hash, options, PeerPutMessage::options, PeerInfo::phash, PeerPutMessage::put_path_length, PeerPutMessage::type, and type.

Referenced by handle_dht_local_put(), and handle_dht_p2p_put().

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 1360 of file gnunet-service-dht_neighbours.c.

1369 {
1370  unsigned int target_count;
1371  struct PeerInfo **targets;
1372  struct PeerInfo *target;
1373  struct GNUNET_MQ_Envelope *env;
1374  size_t msize;
1375  struct PeerGetMessage *pgm;
1376  char *xq;
1377  size_t reply_bf_size;
1378  void *reply_bf;
1379  unsigned int skip_count;
1380  uint32_t bf_nonce;
1381 
1382  GNUNET_assert (NULL != peer_bf);
1384  gettext_noop ("# GET requests routed"),
1385  1,
1386  GNUNET_NO);
1387  target_count = get_target_peers (key,
1388  peer_bf,
1389  hop_count,
1391  &targets);
1393  "Adding myself (%s) to GET bloomfilter for %s\n",
1395  GNUNET_h2s (key));
1397  &my_identity_hash);
1398  if (0 == target_count)
1399  {
1401  "Routing GET for %s terminates after %u hops at %s\n",
1402  GNUNET_h2s (key),
1403  (unsigned int) hop_count,
1404  GNUNET_i2s (&my_identity));
1405  return GNUNET_NO;
1406  }
1407  if (GNUNET_OK !=
1409  &bf_nonce,
1410  &reply_bf,
1411  &reply_bf_size))
1412  {
1413  reply_bf = NULL;
1414  reply_bf_size = 0;
1416  UINT32_MAX);
1417  }
1418  msize = xquery_size + reply_bf_size;
1419  if (msize + sizeof(struct PeerGetMessage) >= GNUNET_MAX_MESSAGE_SIZE)
1420  {
1421  GNUNET_break (0);
1422  GNUNET_free (reply_bf);
1423  GNUNET_free (targets);
1424  return GNUNET_NO;
1425  }
1427  gettext_noop (
1428  "# GET messages queued for transmission"),
1429  target_count,
1430  GNUNET_NO);
1431  /* forward request */
1432  skip_count = 0;
1433  for (unsigned int i = 0; i < target_count; i++)
1434  {
1435  target = targets[i];
1437  {
1438  /* skip */
1440  gettext_noop (
1441  "# P2P messages dropped due to full queue"),
1442  1, GNUNET_NO);
1443  skip_count++;
1444  continue;
1445  }
1447  "Routing GET for %s after %u hops to %s\n",
1448  GNUNET_h2s (key),
1449  (unsigned int) hop_count,
1450  GNUNET_i2s (target->id));
1451  env = GNUNET_MQ_msg_extra (pgm,
1452  msize,
1454  pgm->options = htonl (options);
1455  pgm->type = htonl (type);
1456  pgm->hop_count = htonl (hop_count + 1);
1458  pgm->xquery_size = htonl (xquery_size);
1459  pgm->bf_mutator = bf_nonce;
1462  &target->phash));
1465  pgm->bloomfilter,
1466  DHT_BLOOM_SIZE));
1467  pgm->key = *key;
1468  xq = (char *) &pgm[1];
1469  GNUNET_memcpy (xq,
1470  xquery,
1471  xquery_size);
1472  GNUNET_memcpy (&xq[xquery_size],
1473  reply_bf,
1474  reply_bf_size);
1475  GNUNET_MQ_send (target->mq,
1476  env);
1477  }
1478  GNUNET_free (targets);
1479  GNUNET_free (reply_bf);
1480  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1481 }
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
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:181
#define GNUNET_MESSAGE_TYPE_DHT_P2P_GET
Peer tries to find data in DHT.
uint32_t bf_mutator
Bloomfilter mutator.
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
uint32_t hop_count
Hop count.
uint32_t xquery_size
Size of the extended query.
struct GNUNET_HashCode key
The key we are looking for.
uint32_t type
Desired content type.
uint32_t desired_replication_level
Desired replication level for this request.
uint32_t options
Processing options.

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_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, key, PeerGetMessage::key, MAXIMUM_PENDING_PER_PEER, PeerInfo::mq, my_identity, my_identity_hash, options, PeerGetMessage::options, PeerInfo::phash, PeerGetMessage::type, type, and PeerGetMessage::xquery_size.

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

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 1501 of file gnunet-service-dht_neighbours.c.

1511 {
1512  struct PeerInfo *pi;
1513  struct GNUNET_MQ_Envelope *env;
1514  size_t msize;
1515  struct PeerResultMessage *prm;
1516  struct GNUNET_PeerIdentity *paths;
1517 
1518  msize = data_size + (get_path_length + put_path_length)
1519  * sizeof(struct GNUNET_PeerIdentity);
1520  if ((msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1521  (get_path_length >
1522  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
1523  (put_path_length >
1524  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
1526  {
1527  GNUNET_break (0);
1528  return;
1529  }
1531  target);
1532  if (NULL == pi)
1533  {
1534  /* peer disconnected in the meantime, drop reply */
1536  "No matching peer for reply for key %s\n",
1537  GNUNET_h2s (key));
1538  return;
1539  }
1541  {
1542  /* skip */
1544  gettext_noop (
1545  "# P2P messages dropped due to full queue"),
1546  1,
1547  GNUNET_NO);
1549  "Peer queue full, ignoring reply for key %s\n",
1550  GNUNET_h2s (key));
1551  return;
1552  }
1553 
1555  "Forwarding reply for key %s to peer %s\n",
1556  GNUNET_h2s (key),
1557  GNUNET_i2s (target));
1559  gettext_noop
1560  ("# RESULT messages queued for transmission"), 1,
1561  GNUNET_NO);
1562  env = GNUNET_MQ_msg_extra (prm,
1563  msize,
1565  prm->type = htonl (type);
1566  prm->put_path_length = htonl (put_path_length);
1567  prm->get_path_length = htonl (get_path_length);
1568  prm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1569  prm->key = *key;
1570  paths = (struct GNUNET_PeerIdentity *) &prm[1];
1571  GNUNET_memcpy (paths,
1572  put_path,
1573  put_path_length * sizeof(struct GNUNET_PeerIdentity));
1574  GNUNET_memcpy (&paths[put_path_length],
1575  get_path,
1576  get_path_length * sizeof(struct GNUNET_PeerIdentity));
1577  GNUNET_memcpy (&paths[put_path_length + get_path_length],
1578  data,
1579  data_size);
1580  GNUNET_MQ_send (pi->mq,
1581  env);
1582 }
#define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
Data is returned to peer from DHT.
uint32_t get_path_length
Length of the GET path that follows (if tracked).
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
struct GNUNET_HashCode key
The key of the corresponding GET request.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?

References all_connected_peers, data, data_size, 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(), key, PeerResultMessage::key, MAXIMUM_PENDING_PER_PEER, GNUNET_PEERINFO_Handle::mq, pi, PeerResultMessage::put_path_length, PeerResultMessage::type, and type.

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

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 1592 of file gnunet-service-dht_neighbours.c.

1594 {
1595  (void) cls;
1597  "CORE called, I am %s\n",
1598  GNUNET_i2s (identity));
1599  my_identity = *identity;
1601  sizeof(struct GNUNET_PeerIdentity),
1602  &my_identity_hash);
1604 }
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
struct GNUNET_SERVICE_Handle * GDS_service
Handle for the service.
@ GNUNET_ERROR_TYPE_INFO
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2195

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().

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 1615 of file gnunet-service-dht_neighbours.c.

1617 {
1618  uint32_t putlen;
1619  uint16_t msize;
1620 
1621  (void) cls;
1622  msize = ntohs (put->header.size);
1623  putlen = ntohl (put->put_path_length);
1624  if ((msize <
1625  sizeof(struct PeerPutMessage)
1626  + putlen * sizeof(struct GNUNET_PeerIdentity)) ||
1627  (putlen >
1628  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)))
1629  {
1630  GNUNET_break_op (0);
1631  return GNUNET_SYSERR;
1632  }
1633  return GNUNET_OK;
1634 }
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_PUT.

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

◆ 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 1644 of file gnunet-service-dht_neighbours.c.

1646 {
1647  struct PeerInfo *peer = cls;
1648  const struct GNUNET_PeerIdentity *put_path;
1649  const void *payload;
1650  uint32_t putlen;
1651  uint16_t msize;
1652  size_t payload_size;
1654  struct GNUNET_CONTAINER_BloomFilter *bf;
1655  struct GNUNET_HashCode test_key;
1656  int forwarded;
1657  struct GNUNET_TIME_Absolute exp_time;
1658 
1659  exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time);
1660  if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us)
1661  {
1663  gettext_noop ("# Expired PUTs discarded"),
1664  1,
1665  GNUNET_NO);
1666  return;
1667  }
1668  msize = ntohs (put->header.size);
1669  putlen = ntohl (put->put_path_length);
1671  gettext_noop ("# P2P PUT requests received"),
1672  1,
1673  GNUNET_NO);
1675  gettext_noop ("# P2P PUT bytes received"),
1676  msize,
1677  GNUNET_NO);
1678  put_path = (const struct GNUNET_PeerIdentity *) &put[1];
1679  payload = &put_path[putlen];
1680  options = ntohl (put->options);
1681  payload_size = msize - (sizeof(struct PeerPutMessage)
1682  + putlen * sizeof(struct GNUNET_PeerIdentity));
1683 
1685  "PUT for `%s' from %s\n",
1686  GNUNET_h2s (&put->key),
1687  GNUNET_i2s (peer->id));
1689  {
1690  char *tmp;
1691  char *pp;
1692 
1693  pp = GNUNET_STRINGS_pp2s (put_path,
1694  putlen);
1697  "R5N PUT %s: %s->%s (%u, %u=>%u, PP: %s)\n",
1698  GNUNET_h2s (&put->key),
1699  GNUNET_i2s (peer->id),
1700  tmp,
1701  ntohl (put->hop_count),
1703  &put->key),
1705  &put->key),
1706  pp);
1707  GNUNET_free (pp);
1708  GNUNET_free (tmp);
1709  }
1710  switch (GNUNET_BLOCK_get_key
1712  ntohl (put->type),
1713  payload,
1714  payload_size,
1715  &test_key))
1716  {
1717  case GNUNET_YES:
1718  if (0 != memcmp (&test_key,
1719  &put->key,
1720  sizeof(struct GNUNET_HashCode)))
1721  {
1722  char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
1723 
1724  GNUNET_break_op (0);
1726  "PUT with key `%s' for block with key %s\n",
1727  put_s,
1728  GNUNET_h2s_full (&test_key));
1729  GNUNET_free (put_s);
1730  return;
1731  }
1732  break;
1733 
1734  case GNUNET_NO:
1735  GNUNET_break_op (0);
1736  return;
1737 
1738  case GNUNET_SYSERR:
1739  /* cannot verify, good luck */
1740  break;
1741  }
1742  if (ntohl (put->type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
1743  {
1745  ntohl (put->type),
1746  NULL, /* query group */
1748  NULL, /* query */
1749  NULL, 0, /* xquery */
1750  payload,
1751  payload_size))
1752  {
1755  break;
1756 
1763  default:
1764  GNUNET_break_op (0);
1765  return;
1766  }
1767  }
1768 
1774  &peer->phash));
1775  {
1776  struct GNUNET_PeerIdentity pp[putlen + 1];
1777 
1778  /* extend 'put path' by sender */
1779  if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
1780  {
1781 #if SANITY_CHECKS
1782  for (unsigned int i = 0; i <= putlen; i++)
1783  {
1784  for (unsigned int j = 0; j < i; j++)
1785  {
1786  GNUNET_break (0 != memcmp (&pp[i],
1787  &pp[j],
1788  sizeof(struct GNUNET_PeerIdentity)));
1789  }
1790  GNUNET_break (0 != memcmp (&pp[i],
1791  peer->id,
1792  sizeof(struct GNUNET_PeerIdentity)));
1793  }
1794 #endif
1795  GNUNET_memcpy (pp,
1796  put_path,
1797  putlen * sizeof(struct GNUNET_PeerIdentity));
1798  pp[putlen] = *peer->id;
1799  putlen++;
1800  }
1801  else
1802  putlen = 0;
1803 
1804  /* give to local clients */
1805  GDS_CLIENTS_handle_reply (exp_time,
1806  &put->key,
1807  0,
1808  NULL,
1809  putlen,
1810  pp,
1811  ntohl (put->type),
1812  payload_size,
1813  payload);
1814  /* store locally */
1816  (GDS_am_closest_peer (&put->key, bf)))
1817  GDS_DATACACHE_handle_put (exp_time,
1818  &put->key,
1819  putlen,
1820  pp,
1821  ntohl (put->type),
1822  payload_size,
1823  payload);
1824  /* route to other peers */
1825  forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type),
1826  options,
1827  ntohl (
1829  exp_time,
1830  ntohl (put->hop_count),
1831  bf,
1832  &put->key,
1833  putlen,
1834  pp,
1835  payload,
1836  payload_size);
1837  /* notify monitoring clients */
1839  | ((GNUNET_OK == forwarded)
1841  : 0),
1842  ntohl (put->type),
1843  ntohl (put->hop_count),
1844  ntohl (put->desired_replication_level),
1845  putlen, pp,
1846  exp_time,
1847  &put->key,
1848  payload,
1849  payload_size);
1850  }
1852 }
static unsigned long long payload
How much data are we currently storing in the database?
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.
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've received from another peer.
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've received from another peer.
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.
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.
static int log_route_details_stderr
Should routing details be logged to stderr (for debugging)?
#define LOG_TRAFFIC(kind,...)
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:379
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:339
@ GNUNET_BLOCK_EVALUATION_RESULT_INVALID
Block does not match query (invalid result)
@ GNUNET_BLOCK_EVALUATION_REQUEST_INVALID
Query format does not match block type (invalid query).
@ GNUNET_BLOCK_EVALUATION_OK_LAST
Last possible valid result.
@ GNUNET_BLOCK_EVALUATION_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT
Block does not match xquery (valid result, not relevant for the request)
@ GNUNET_BLOCK_EVALUATION_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED
Specified block type not supported by this plugin.
@ GNUNET_BLOCK_EVALUATION_REQUEST_VALID
Query is valid, no reply given.
@ GNUNET_BLOCK_EO_NONE
Default behavior.
@ GNUNET_BLOCK_TYPE_REGEX
Block to store a cadet regex state.
GNUNET_DHT_RouteOption
Options for routing.
@ GNUNET_DHT_RO_LAST_HOP
Flag given to monitors if this was the last hop for a GET/PUT.
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should look at 'enc' (otherwise only the k-peers closest to the key should lo...
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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:73
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:232
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:542
Time for absolute times used by GNUnet, in microseconds.

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, PeerPutMessage::key, log_route_details_stderr, LOG_TRAFFIC, my_identity, my_identity_hash, options, PeerPutMessage::options, payload, peer, PeerPutMessage::put_path_length, GNUNET_MessageHeader::size, and PeerPutMessage::type.

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 1864 of file gnunet-service-dht_neighbours.c.

1867 {
1868  int bucket_idx;
1869  struct PeerBucket *bucket;
1870  struct PeerInfo *peer;
1871  unsigned int choice;
1872  const struct GNUNET_HELLO_Message *hello;
1873  size_t hello_size;
1874 
1875  /* first, check about our own HELLO */
1876  if (NULL != GDS_my_hello)
1877  {
1878  hello_size = GNUNET_HELLO_size ((const struct
1880  GNUNET_break (hello_size >= sizeof(struct GNUNET_MessageHeader));
1884  bg,
1887  NULL, 0,
1888  GDS_my_hello,
1889  hello_size))
1890  {
1895  key,
1896  0,
1897  NULL,
1898  0,
1899  NULL,
1900  GDS_my_hello,
1901  hello_size);
1902  }
1903  else
1904  {
1906  gettext_noop (
1907  "# FIND PEER requests ignored due to Bloomfilter"),
1908  1,
1909  GNUNET_NO);
1910  }
1911  }
1912  else
1913  {
1915  gettext_noop (
1916  "# FIND PEER requests ignored due to lack of HELLO"),
1917  1,
1918  GNUNET_NO);
1919  }
1920 
1921  /* then, also consider sending a random HELLO from the closest bucket */
1922  if (0 == memcmp (&my_identity_hash,
1923  key,
1924  sizeof(struct GNUNET_HashCode)))
1925  bucket_idx = closest_bucket;
1926  else
1927  bucket_idx = GNUNET_MIN ((int) closest_bucket,
1928  find_bucket (key));
1929  if (bucket_idx < 0)
1930  return;
1931  bucket = &k_buckets[bucket_idx];
1932  if (bucket->peers_size == 0)
1933  return;
1935  bucket->peers_size);
1936  peer = bucket->head;
1937  while (choice > 0)
1938  {
1939  GNUNET_assert (NULL != peer);
1940  peer = peer->next;
1941  choice--;
1942  }
1943  choice = bucket->peers_size;
1944  do
1945  {
1946  peer = peer->next;
1947  if (0 == choice--)
1948  return; /* no non-masked peer available */
1949  if (NULL == peer)
1950  peer = bucket->head;
1951  hello = GDS_HELLO_get (peer->id);
1952  }
1953  while ((NULL == hello) ||
1957  bg,
1959  &peer->phash,
1960  NULL, 0,
1961  hello,
1962  (hello_size = GNUNET_HELLO_size (hello)))));
1967  key,
1968  0,
1969  NULL,
1970  0,
1971  NULL,
1972  hello,
1973  hello_size);
1974 }
struct GNUNET_MessageHeader * GDS_my_hello
Our HELLO.
const struct GNUNET_HELLO_Message * GDS_HELLO_get(const struct GNUNET_PeerIdentity *peer)
Obtain a peer's HELLO if available.
struct GNUNET_TIME_Relative hello_expiration
Hello address expiration.
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).
@ GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO
The block is obtained from the local database, skip cryptographic checks.
#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...
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
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:181
A HELLO message is used to exchange information about transports with other peers.
Header for all communications.
struct GNUNET_TESTBED_Peer * next
peer list DLL
Peers are grouped into buckets.

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, k_buckets, key, my_identity_hash, GNUNET_TESTBED_Peer::next, peer, and PeerBucket::peers_size.

Referenced by handle_dht_p2p_get().

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 1992 of file gnunet-service-dht_neighbours.c.

2002 {
2003  struct PeerInfo *peer = cls;
2004  char *pp;
2005 
2006  pp = GNUNET_STRINGS_pp2s (put_path,
2007  put_path_length);
2009  "Found local result for %s (PP: %s)\n",
2010  GNUNET_h2s (key),
2011  pp);
2012  GNUNET_free (pp);
2014  type,
2015  expiration_time,
2016  key,
2017  put_path_length, put_path,
2018  get_path_length, get_path,
2019  data, data_size);
2020 }

References data, data_size, GDS_NEIGHBOURS_handle_reply(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_STRINGS_pp2s(), key, peer, and type.

Referenced by handle_dht_p2p_get().

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 2031 of file gnunet-service-dht_neighbours.c.

2033 {
2034  uint32_t xquery_size;
2035  uint16_t msize;
2036 
2037  (void) cls;
2038  msize = ntohs (get->header.size);
2039  xquery_size = ntohl (get->xquery_size);
2040  if (msize < sizeof(struct PeerGetMessage) + xquery_size)
2041  {
2042  GNUNET_break_op (0);
2043  return GNUNET_SYSERR;
2044  }
2045  return GNUNET_OK;
2046 }
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_GET.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, PeerGetMessage::header, GNUNET_MessageHeader::size, and PeerGetMessage::xquery_size.

◆ 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 2056 of file gnunet-service-dht_neighbours.c.

2058 {
2059  struct PeerInfo *peer = cls;
2060  uint32_t xquery_size;
2061  size_t reply_bf_size;
2062  uint16_t msize;
2063  enum GNUNET_BLOCK_Type type;
2066  struct GNUNET_BLOCK_Group *bg;
2067  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
2068  const char *xquery;
2069  int forwarded;
2070 
2071  /* parse and validate message */
2072  msize = ntohs (get->header.size);
2073  xquery_size = ntohl (get->xquery_size);
2074  reply_bf_size = msize - (sizeof(struct PeerGetMessage) + xquery_size);
2075  type = ntohl (get->type);
2076  options = ntohl (get->options);
2077  xquery = (const char *) &get[1];
2079  gettext_noop ("# P2P GET requests received"),
2080  1,
2081  GNUNET_NO);
2083  gettext_noop ("# P2P GET bytes received"),
2084  msize,
2085  GNUNET_NO);
2087  {
2088  char *tmp;
2089 
2092  "R5N GET %s: %s->%s (%u, %u=>%u) xq: %.*s\n",
2093  GNUNET_h2s (&get->key),
2094  GNUNET_i2s (peer->id),
2095  tmp,
2096  ntohl (get->hop_count),
2098  &get->key),
2100  &get->key),
2101  ntohl (get->xquery_size),
2102  xquery);
2103  GNUNET_free (tmp);
2104  }
2105  eval
2107  type,
2108  NULL,
2110  &get->key,
2111  xquery,
2112  xquery_size,
2113  NULL,
2114  0);
2116  {
2117  /* request invalid or block type not supported */
2119  return;
2120  }
2126  &peer->phash));
2128  type,
2129  get->bf_mutator,
2130  &xquery[xquery_size],
2131  reply_bf_size,
2132  "filter-size",
2133  reply_bf_size,
2134  NULL);
2136  "GET for %s at %s after %u hops\n",
2137  GNUNET_h2s (&get->key),
2139  (unsigned int) ntohl (get->hop_count));
2140  /* local lookup (this may update the reply_bf) */
2142  (GDS_am_closest_peer (&get->key,
2143  peer_bf)))
2144  {
2145  if ((0 != (options & GNUNET_DHT_RO_FIND_PEER)))
2146  {
2148  gettext_noop (
2149  "# P2P FIND PEER requests processed"),
2150  1,
2151  GNUNET_NO);
2152  handle_find_peer (peer->id,
2153  &get->key,
2154  bg);
2155  }
2156  else
2157  {
2158  eval = GDS_DATACACHE_handle_get (&get->key,
2159  type,
2160  xquery,
2161  xquery_size,
2162  bg,
2164  peer);
2165  }
2166  }
2167  else
2168  {
2170  gettext_noop ("# P2P GET requests ONLY routed"),
2171  1,
2172  GNUNET_NO);
2173  }
2174 
2175  /* remember request for routing replies */
2176  GDS_ROUTING_add (peer->id,
2177  type,
2178  bg, /* bg now owned by routing, but valid at least until end of this function! */
2179  options,
2180  &get->key,
2181  xquery,
2182  xquery_size);
2183 
2184  /* P2P forwarding */
2185  forwarded = GNUNET_NO;
2186  if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST)
2187  forwarded = GDS_NEIGHBOURS_handle_get (type,
2188  options,
2189  ntohl (
2191  ntohl (get->hop_count),
2192  &get->key,
2193  xquery,
2194  xquery_size,
2195  bg,
2196  peer_bf);
2198  | ((GNUNET_OK == forwarded)
2199  ? GNUNET_DHT_RO_LAST_HOP : 0),
2200  type,
2201  ntohl (get->hop_count),
2202  ntohl (get->desired_replication_level),
2203  0,
2204  NULL,
2205  &get->key);
2206 
2207  /* clean up; note that 'bg' is owned by routing now! */
2209 }
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.
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've received from another peer.
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.
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.
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.
GNUNET_BLOCK_EvaluationResult
Possible ways for how a block may relate to a query.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.

References PeerGetMessage::bf_mutator, PeerGetMessage::bloomfilter, PeerGetMessage::desired_replication_level, 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(), PeerGetMessage::header, PeerGetMessage::hop_count, PeerGetMessage::key, log_route_details_stderr, LOG_TRAFFIC, my_identity, my_identity_hash, options, PeerGetMessage::options, peer, GNUNET_MessageHeader::size, PeerGetMessage::type, type, and PeerGetMessage::xquery_size.

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 2220 of file gnunet-service-dht_neighbours.c.

2222 {
2223  uint32_t get_path_length;
2224  uint32_t put_path_length;
2225  uint16_t msize;
2226 
2227  (void) cls;
2228  msize = ntohs (prm->header.size);
2229  put_path_length = ntohl (prm->put_path_length);
2230  get_path_length = ntohl (prm->get_path_length);
2231  if ((msize <
2232  sizeof(struct PeerResultMessage) + (get_path_length
2233  + put_path_length)
2234  * sizeof(struct GNUNET_PeerIdentity)) ||
2235  (get_path_length >
2236  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ||
2237  (put_path_length >
2238  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)))
2239  {
2240  GNUNET_break_op (0);
2241  return GNUNET_SYSERR;
2242  }
2243  return GNUNET_OK;
2244 }
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT.

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

◆ 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 2261 of file gnunet-service-dht_neighbours.c.

2270 {
2271  /* forward to local clients */
2272  GDS_CLIENTS_handle_reply (expiration_time,
2273  key,
2274  get_path_length,
2275  get_path,
2276  put_path_length,
2277  put_path,
2278  type,
2279  data_size,
2280  data);
2282  get_path,
2283  get_path_length,
2284  put_path,
2285  put_path_length,
2286  expiration_time,
2287  key,
2288  data,
2289  data_size);
2290  if (GNUNET_YES == cache_results)
2291  {
2292  struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length];
2293 
2294  GNUNET_memcpy (xput_path,
2295  put_path,
2296  put_path_length * sizeof(struct GNUNET_PeerIdentity));
2297  GNUNET_memcpy (&xput_path[put_path_length],
2298  get_path,
2299  get_path_length * sizeof(struct GNUNET_PeerIdentity));
2300 
2301  GDS_DATACACHE_handle_put (expiration_time,
2302  key,
2303  get_path_length + put_path_length,
2304  xput_path,
2305  type,
2306  data_size,
2307  data);
2308  }
2309  /* forward to other peers */
2311  expiration_time,
2312  key,
2313  put_path_length,
2314  put_path,
2315  get_path_length,
2316  get_path,
2317  data,
2318  data_size);
2319 }
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.
static int cache_results
Do we cache all results that we are routing in the local datacache?
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).

References cache_results, data, data_size, GDS_CLIENTS_handle_reply(), GDS_CLIENTS_process_get_resp(), GDS_DATACACHE_handle_put(), GDS_ROUTING_process(), GNUNET_memcpy, GNUNET_YES, key, and type.

Referenced by handle_dht_p2p_result().

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 2329 of file gnunet-service-dht_neighbours.c.

2331 {
2332  struct PeerInfo *peer = cls;
2333  const struct GNUNET_PeerIdentity *put_path;
2334  const struct GNUNET_PeerIdentity *get_path;
2335  const void *data;
2336  uint32_t get_path_length;
2337  uint32_t put_path_length;
2338  uint16_t msize;
2339  size_t data_size;
2340  enum GNUNET_BLOCK_Type type;
2341  struct GNUNET_TIME_Absolute exp_time;
2342 
2343  /* parse and validate message */
2344  exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time);
2345  if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us)
2346  {
2348  gettext_noop ("# Expired results discarded"),
2349  1,
2350  GNUNET_NO);
2351  return;
2352  }
2353  msize = ntohs (prm->header.size);
2354  put_path_length = ntohl (prm->put_path_length);
2355  get_path_length = ntohl (prm->get_path_length);
2356  put_path = (const struct GNUNET_PeerIdentity *) &prm[1];
2357  get_path = &put_path[put_path_length];
2358  type = ntohl (prm->type);
2359  data = (const void *) &get_path[get_path_length];
2360  data_size = msize - (sizeof(struct PeerResultMessage)
2361  + (get_path_length
2362  + put_path_length) * sizeof(struct
2365  gettext_noop ("# P2P RESULTS received"),
2366  1,
2367  GNUNET_NO);
2369  gettext_noop ("# P2P RESULT bytes received"),
2370  msize,
2371  GNUNET_NO);
2373  {
2374  char *tmp;
2375  char *pp;
2376  char *gp;
2377 
2378  gp = GNUNET_STRINGS_pp2s (get_path,
2379  get_path_length);
2380  pp = GNUNET_STRINGS_pp2s (put_path,
2381  put_path_length);
2384  "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n",
2385  GNUNET_h2s (&prm->key),
2386  GNUNET_i2s (peer->id),
2387  tmp,
2388  gp,
2389  pp);
2390  GNUNET_free (gp);
2391  GNUNET_free (pp);
2392  GNUNET_free (tmp);
2393  }
2394  /* if we got a HELLO, consider it for our own routing table */
2396  {
2397  const struct GNUNET_MessageHeader *h;
2398  struct GNUNET_PeerIdentity pid;
2399 
2400  /* Should be a HELLO, validate and consider using it! */
2401  if (data_size < sizeof(struct GNUNET_HELLO_Message))
2402  {
2403  GNUNET_break_op (0);
2404  return;
2405  }
2406  h = data;
2407  if (data_size != ntohs (h->size))
2408  {
2409  GNUNET_break_op (0);
2410  return;
2411  }
2412  if (GNUNET_OK !=
2413  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) h,
2414  &pid))
2415  {
2416  GNUNET_break_op (0);
2417  return;
2418  }
2419  if ((GNUNET_YES != disable_try_connect) &&
2420  (0 != memcmp (&my_identity,
2421  &pid,
2422  sizeof(struct GNUNET_PeerIdentity))))
2423  try_connect (&pid,
2424  h);
2425  }
2426 
2427  /* First, check if 'peer' is already on the path, and if
2428  so, truncate it instead of expanding. */
2429  for (unsigned int i = 0; i <= get_path_length; i++)
2430  if (0 == memcmp (&get_path[i],
2431  peer->id,
2432  sizeof(struct GNUNET_PeerIdentity)))
2433  {
2434  process_reply_with_path (exp_time,
2435  &prm->key,
2436  i,
2437  get_path,
2438  put_path_length,
2439  put_path,
2440  type,
2441  data_size,
2442  data);
2443  return;
2444  }
2445 
2446  /* Need to append 'peer' to 'get_path' (normal case) */
2447  {
2448  struct GNUNET_PeerIdentity xget_path[get_path_length + 1];
2449 
2450  GNUNET_memcpy (xget_path,
2451  get_path,
2452  get_path_length * sizeof(struct GNUNET_PeerIdentity));
2453  xget_path[get_path_length] = *peer->id;
2454 
2455  process_reply_with_path (exp_time,
2456  &prm->key,
2457  get_path_length + 1,
2458  xget_path,
2459  put_path_length,
2460  put_path,
2461  type,
2462  data_size,
2463  data);
2464  }
2465 }
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.
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

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, PeerResultMessage::key, log_route_details_stderr, LOG_TRAFFIC, my_identity, peer, pid, process_reply_with_path(), PeerResultMessage::put_path_length, GNUNET_MessageHeader::size, try_connect(), PeerResultMessage::type, and type.

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 2474 of file gnunet-service-dht_neighbours.c.

2475 {
2476  struct GNUNET_MQ_MessageHandler core_handlers[] = {
2477  GNUNET_MQ_hd_var_size (dht_p2p_get,
2479  struct PeerGetMessage,
2480  NULL),
2481  GNUNET_MQ_hd_var_size (dht_p2p_put,
2483  struct PeerPutMessage,
2484  NULL),
2485  GNUNET_MQ_hd_var_size (dht_p2p_result,
2487  struct PeerResultMessage,
2488  NULL),
2490  };
2491  unsigned long long temp_config_num;
2492 
2495  "DHT",
2496  "DISABLE_TRY_CONNECT");
2497  if (GNUNET_OK ==
2499  "DHT",
2500  "bucket_size",
2501  &temp_config_num))
2502  bucket_size = (unsigned int) temp_config_num;
2505  "DHT",
2506  "CACHE_RESULTS");
2507 
2509  (NULL != getenv ("GNUNET_DHT_ROUTE_DEBUG")) ? GNUNET_YES : GNUNET_NO;
2512  NULL,
2513  &core_init,
2516  core_handlers);
2517  if (NULL == core_api)
2518  return GNUNET_SYSERR;
2520  GNUNET_YES);
2522  GNUNET_NO);
2523  return GNUNET_OK;
2524 }
char * getenv()
static void core_init(void *cls, const struct GNUNET_PeerIdentity *identity)
To be called on core init/fail.
static struct GNUNET_CORE_Handle * core_api
Handle to CORE.
static void handle_core_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a peer disconnects.
static void * handle_core_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a peer connects.
struct GNUNET_ATS_ConnectivityHandle * GNUNET_ATS_connectivity_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the ATS connectivity suggestion client handle.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_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".
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
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
Message handler for a specific message type.

References all_connected_peers, all_desired_peers, ats_ch, bucket_size, cache_results, core_api, 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(), consensus-simulation::int, and log_route_details_stderr.

Referenced by run().

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 2531 of file gnunet-service-dht_neighbours.c.

2532 {
2533  if (NULL == core_api)
2534  return;
2536  core_api = NULL;
2537  GNUNET_assert (0 ==
2540  all_connected_peers = NULL;
2543  NULL);
2545  all_desired_peers = NULL;
2547  ats_ch = NULL;
2548  GNUNET_assert (NULL == find_peer_task);
2549 }
void GNUNET_ATS_connectivity_done(struct GNUNET_ATS_ConnectivityHandle *ch)
Client is done with ATS connectivity management, release resources.
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:730
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.

References all_connected_peers, all_desired_peers, ats_ch, core_api, find_peer_task, 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().

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 2558 of file gnunet-service-dht_neighbours.c.

2559 {
2560  return &my_identity;
2561 }

Referenced by handle_dht_local_get(), and handle_dht_local_put().

Here is the caller graph for this function:

Variable Documentation

◆ hello_expiration

struct GNUNET_TIME_Relative hello_expiration
extern

Hello address expiration.

Definition at line 50 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 368 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.

Referenced by GDS_NEIGHBOURS_done(), GDS_NEIGHBOURS_handle_reply(), GDS_NEIGHBOURS_init(), get_target_peers(), handle_core_connect(), handle_core_disconnect(), send_find_peer_message(), and try_connect().

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

Referenced by free_connect_info(), GDS_NEIGHBOURS_done(), GDS_NEIGHBOURS_init(), try_connect(), and update_connect_preferences().

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

Referenced by GDS_NEIGHBOURS_done(), handle_core_connect(), handle_core_disconnect(), and send_find_peer_message().

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

Referenced by GDS_NEIGHBOURS_done(), and GDS_NEIGHBOURS_init().

◆ ats_ch

struct GNUNET_ATS_ConnectivityHandle* ats_ch
static

Handle to ATS connectivity.

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

Referenced by GDS_NEIGHBOURS_done(), GDS_NEIGHBOURS_init(), and try_connect().