GNUnet  0.11.x
Functions
gnunet-service-dht_neighbours.h File Reference

GNUnet DHT routing code. More...

#include "gnunet_util_lib.h"
#include "gnunet_block_lib.h"
#include "gnunet_dht_service.h"
#include "gnunet_dhtu_plugin.h"
#include "gnunet-service-dht_datacache.h"
Include dependency graph for gnunet-service-dht_neighbours.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

struct PeerInfoGDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target)
 Lookup peer by peer's identity. More...
 
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, enum GNUNET_DHT_RouteOption options, uint16_t desired_replication_level, uint16_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf)
 Perform a PUT operation. More...
 
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint16_t desired_replication_level, uint16_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...
 
bool GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, const struct GDS_DATACACHE_BlockData *bd, const struct GNUNET_HashCode *query_hash, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *get_path)
 Handle a reply (route to origin). More...
 
enum GNUNET_GenericReturnValue 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...
 
void GDS_try_connect (void *cls, const char *uri)
 Callback function used to extract URIs from a builder. More...
 
void GDS_u_connect (void *cls, struct GNUNET_DHTU_Target *target, const struct GNUNET_PeerIdentity *pid, void **ctx)
 Function to call when we connect to a peer and can henceforth transmit to that peer. More...
 
void GDS_u_disconnect (void *ctx)
 Function to call when we disconnected from a peer and can henceforth cannot transmit to that peer anymore. More...
 
void GDS_u_receive (void *cls, void **tctx, void **sctx, const void *message, size_t message_size)
 Function to call when we receive a message. More...
 
void GDS_NEIGHBOURS_broadcast (const struct GNUNET_MessageHeader *msg)
 Send msg to all peers in our buckets. More...
 
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_init (void)
 Initialize neighbours subsystem. More...
 
void GDS_NEIGHBOURS_done (void)
 Shutdown neighbours subsystem. More...
 
struct GNUNET_PeerIdentityGDS_NEIGHBOURS_get_id (void)
 Get the ID of the local node. More...
 

Detailed Description

GNUnet DHT routing code.

Author
Christian Grothoff
Nathan Evans

Definition in file gnunet-service-dht_neighbours.h.

Function Documentation

◆ GDS_NEIGHBOURS_lookup_peer()

struct PeerInfo* GDS_NEIGHBOURS_lookup_peer ( const struct GNUNET_PeerIdentity target)

Lookup peer by peer's identity.

Parameters
targetpeer to look up
Returns
NULL if we are not connected to target

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

1572 {
1574  target);
1575 }
static struct GNUNET_CONTAINER_MultiPeerMap * all_connected_peers
Hash map of all CORE-connected peers, for easy removal from k_buckets on disconnect.
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.

References all_connected_peers, and GNUNET_CONTAINER_multipeermap_get().

Here is the call graph for this function:

◆ GDS_NEIGHBOURS_handle_put()

enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_put ( const struct GDS_DATACACHE_BlockData bd,
enum GNUNET_DHT_RouteOption  options,
uint16_t  desired_replication_level,
uint16_t  hop_count,
struct GNUNET_CONTAINER_BloomFilter bf 
)

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
bddata about the block
optionsrouting options
desired_replication_leveldesired replication level
hop_counthow many hops has this message traversed so far
bfBloom filter of peers this PUT has already traversed
Returns
GNUNET_OK if the request was forwarded, GNUNET_NO if not

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

1320 {
1321  unsigned int target_count;
1322  struct PeerInfo **targets;
1323  size_t msize;
1324  unsigned int skip_count;
1325  unsigned int put_path_length = bd->put_path_length;
1326 
1327  GNUNET_assert (NULL != bf);
1328 #if SANITY_CHECKS > 1
1329  if (0 !=
1331  bd->data_size,
1332  bd->expiration_time,
1333  bd->put_path,
1334  bd->put_path_length,
1335  NULL, 0, /* get_path */
1336  &GDS_my_identity))
1337  {
1338  GNUNET_break_op (0);
1339  put_path_length = 0;
1340  }
1341 #endif
1343  "Adding myself (%s) to PUT bloomfilter for %s with RO(%s/%s)\n",
1345  GNUNET_h2s (&bd->key),
1347  (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1348 
1349  /* if we got a HELLO, consider it for our own routing table */
1350  hello_check (bd);
1354  "# PUT requests routed",
1355  1,
1356  GNUNET_NO);
1357  target_count
1358  = get_target_peers (&bd->key,
1359  bf,
1360  hop_count,
1361  desired_replication_level,
1362  &targets);
1363  if (0 == target_count)
1364  {
1366  "Routing PUT for %s terminates after %u hops at %s\n",
1367  GNUNET_h2s (&bd->key),
1368  (unsigned int) hop_count,
1370  return GNUNET_NO;
1371  }
1372  msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)
1373  + bd->data_size;
1374  if (msize + sizeof(struct PeerPutMessage)
1376  {
1377  put_path_length = 0;
1378  msize = bd->data_size;
1379  }
1380  if (msize + sizeof(struct PeerPutMessage)
1382  {
1383  GNUNET_break (0);
1384  GNUNET_free (targets);
1385  return GNUNET_NO;
1386  }
1387  skip_count = 0;
1388  for (unsigned int i = 0; i < target_count; i++)
1389  {
1390  struct PeerInfo *target = targets[i];
1391  struct PeerPutMessage *ppm;
1392  char buf[sizeof (*ppm) + msize] GNUNET_ALIGN;
1393  struct GNUNET_DHT_PathElement *pp;
1394 
1396  "Routing PUT for %s after %u hops to %s\n",
1397  GNUNET_h2s (&bd->key),
1398  (unsigned int) hop_count,
1399  GNUNET_i2s (&target->id));
1400  ppm = (struct PeerPutMessage *) buf;
1402  ppm->header.size = htons (sizeof (buf));
1403  ppm->type = htonl (bd->type);
1404  ppm->options = htons (options);
1405  ppm->hop_count = htons (hop_count + 1);
1407  ppm->put_path_length = htons (put_path_length);
1411  &target->phash));
1414  ppm->bloomfilter,
1415  DHT_BLOOM_SIZE));
1416  ppm->key = bd->key;
1417  pp = (struct GNUNET_DHT_PathElement *) &ppm[1];
1418  GNUNET_memcpy (pp,
1419  bd->put_path,
1420  sizeof (struct GNUNET_DHT_PathElement) * put_path_length);
1421  /* 0 == put_path_length means path is not being tracked */
1422  if (0 != put_path_length)
1423  {
1424  /* Note that the signature in 'put_path' was not initialized before,
1425  so this is crucial to avoid sending garbage. */
1426  sign_path (bd->data,
1427  bd->data_size,
1428  bd->expiration_time,
1429  &pp[put_path_length - 1].pred,
1430  &target->id,
1431  &pp[put_path_length - 1].sig);
1433  "Signing PUT PATH %u => %s\n",
1434  put_path_length,
1435  GNUNET_B2S (&pp[put_path_length - 1].sig));
1436  }
1437 
1438  GNUNET_memcpy (&pp[put_path_length],
1439  bd->data,
1440  bd->data_size);
1441  do_send (target,
1442  &ppm->header);
1443  }
1444  GNUNET_free (targets);
1446  "# PUT messages queued for transmission",
1447  target_count - skip_count,
1448  GNUNET_NO);
1449  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1450 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct GNUNET_PeerIdentity GDS_my_identity
Identity of this peer.
struct GNUNET_HashCode GDS_my_identity_hash
Hash of the identity of this peer.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
static void do_send(struct PeerInfo *pi, const struct GNUNET_MessageHeader *msg)
Send msg to pi.
static unsigned int get_target_peers(const struct GNUNET_HashCode *key, struct GNUNET_CONTAINER_BloomFilter *bloom, uint16_t hop_count, uint16_t target_replication, struct PeerInfo ***targets)
Compute the set of peers that the given request should be forwarded to.
static void sign_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_PeerIdentity *pred, const struct GNUNET_PeerIdentity *succ, struct GNUNET_CRYPTO_EddsaSignature *sig)
Sign that we are routing a message from pred to succ.
static void hello_check(const struct GDS_DATACACHE_BlockData *bd)
If we got a HELLO, consider it for our own routing table.
static char buf[2048]
#define GNUNET_log(kind,...)
#define GNUNET_B2S(obj)
Convert a fixed-sized object to a string using GNUNET_b2s().
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
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.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
#define GNUNET_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_DHT_verify_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_len, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_len, const struct GNUNET_PeerIdentity *me)
Verify signatures on a path consisting of put_path and get_path in reverse order (starting at the las...
Definition: dht_api.c:1303
@ GNUNET_DHT_RO_RECORD_ROUTE
We should keep track of the route that the message took in the P2P network.
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
Peer is storing data in DHT.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
const void * data
Actual block data.
size_t data_size
Number of bytes in data.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
enum GNUNET_BLOCK_Type type
Type of the block.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_HashCode key
Key of the block.
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
struct GNUNET_CRYPTO_EddsaSignature sig
Signature affirming the hop of type GNUNET_SIGNATURE_PURPOSE_DHT_HOP.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Entry for a peer in a bucket.
struct GNUNET_PeerIdentity id
What is the identity of the peer?
struct GNUNET_HashCode phash
Hash of id.
uint16_t desired_replication_level
Replication level for this message.
uint16_t hop_count
Hop count.
uint32_t type
Content type.
char bloomfilter[128]
Bloomfilter (for peer identities) to stop circular routes.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_PUT.
struct GNUNET_HashCode key
The key we are storing under.
uint16_t options
Processing options.
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
uint16_t put_path_length
Length of the PUT path that follows (if tracked).

Referenced by handle_dht_local_put(), and handle_dht_p2p_put().

Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_handle_get()

enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_get ( enum GNUNET_BLOCK_Type  type,
enum GNUNET_DHT_RouteOption  options,
uint16_t  desired_replication_level,
uint16_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
bgblock group to filter replies
peer_bffilter for peers not to select (again, updated)
Returns
GNUNET_OK if the request was forwarded, GNUNET_NO if not

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

1463 {
1464  unsigned int target_count;
1465  struct PeerInfo **targets;
1466  size_t msize;
1467  size_t reply_bf_size;
1468  void *reply_bf;
1469  unsigned int skip_count;
1470  uint32_t bf_nonce;
1471 
1472  GNUNET_assert (NULL != peer_bf);
1474  "# GET requests routed",
1475  1,
1476  GNUNET_NO);
1477  target_count = get_target_peers (key,
1478  peer_bf,
1479  hop_count,
1480  desired_replication_level,
1481  &targets);
1483  "Adding myself (%s) to GET bloomfilter for %s with RO(%s/%s)\n",
1485  GNUNET_h2s (key),
1487  (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1488 
1491  if (0 == target_count)
1492  {
1494  "Routing GET for %s terminates after %u hops at %s\n",
1495  GNUNET_h2s (key),
1496  (unsigned int) hop_count,
1498  return GNUNET_NO;
1499  }
1500  if (GNUNET_OK !=
1502  &bf_nonce,
1503  &reply_bf,
1504  &reply_bf_size))
1505  {
1506  reply_bf = NULL;
1507  reply_bf_size = 0;
1509  UINT32_MAX);
1510  }
1511  msize = xquery_size + reply_bf_size;
1512  if (msize + sizeof(struct PeerGetMessage) >= GNUNET_MAX_MESSAGE_SIZE)
1513  {
1514  GNUNET_break (0);
1515  GNUNET_free (reply_bf);
1516  GNUNET_free (targets);
1517  return GNUNET_NO;
1518  }
1519  /* forward request */
1520  skip_count = 0;
1521  for (unsigned int i = 0; i < target_count; i++)
1522  {
1523  struct PeerInfo *target = targets[i];
1524  struct PeerGetMessage *pgm;
1525  char buf[sizeof (*pgm) + msize] GNUNET_ALIGN;
1526  char *xq;
1527 
1529  "Routing GET for %s after %u hops to %s\n",
1530  GNUNET_h2s (key),
1531  (unsigned int) hop_count,
1532  GNUNET_i2s (&target->id));
1533  pgm = (struct PeerGetMessage *) buf;
1535  pgm->header.size = htons (sizeof (buf));
1536  pgm->type = htonl (type);
1537  pgm->options = htons (options);
1538  pgm->hop_count = htons (hop_count + 1);
1540  pgm->xquery_size = htonl (xquery_size);
1541  pgm->bf_mutator = bf_nonce;
1544  &target->phash));
1547  pgm->bloomfilter,
1548  DHT_BLOOM_SIZE));
1549  pgm->key = *key;
1550  xq = (char *) &pgm[1];
1551  GNUNET_memcpy (xq,
1552  xquery,
1553  xquery_size);
1554  GNUNET_memcpy (&xq[xquery_size],
1555  reply_bf,
1556  reply_bf_size);
1557  do_send (target,
1558  &pgm->header);
1559  }
1561  "# GET messages queued for transmission",
1562  target_count - skip_count,
1563  GNUNET_NO);
1564  GNUNET_free (targets);
1565  GNUNET_free (reply_bf);
1566  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1567 }
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue 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:153
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).
#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.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_GET.
uint16_t hop_count
Hop count.
uint16_t desired_replication_level
Desired replication level for this request.
uint16_t xquery_size
Size of the extended query.
uint16_t options
Processing options.
struct GNUNET_HashCode key
The key we are looking for.
uint32_t type
Desired content type.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References GDS_DATACACHE_BlockData::data, GDS_DATACACHE_BlockData::data_size, disable_try_connect, GDS_try_connect(), GNUNET_BLOCK_TYPE_DHT_URL_HELLO, GNUNET_HELLO_builder_free(), GNUNET_HELLO_builder_from_block(), GNUNET_HELLO_builder_iterate(), GNUNET_YES, pid, and GDS_DATACACHE_BlockData::type.

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

bool GDS_NEIGHBOURS_handle_reply ( struct PeerInfo pi,
const struct GDS_DATACACHE_BlockData bd,
const struct GNUNET_HashCode query_hash,
unsigned int  get_path_length,
const struct GNUNET_DHT_PathElement get_path 
)

Handle a reply (route to origin).

Only forwards the reply back to other peers waiting for it. Does not do local caching or forwarding to local clients.

Parameters
pineighbour that should receive the block
typetype of the block
bddetails about the reply
query_hashquery that was used for the request
get_path_lengthnumber of entries in put_path
get_pathpeers this reply has traversed so far (if tracked)
Returns
true on success

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

1584 {
1585  struct GNUNET_DHT_PathElement *paths;
1586  size_t msize;
1587  unsigned int ppl = bd->put_path_length;
1588 
1589 #if SANITY_CHECKS > 1
1590  if (0 !=
1592  bd->data_size,
1593  bd->expiration_time,
1594  bd->put_path,
1595  bd->put_path_length,
1596  get_path,
1597  get_path_length,
1598  &GDS_my_identity))
1599  {
1600  GNUNET_break_op (0);
1601  return false;
1602  }
1603 #endif
1604  msize = bd->data_size + (get_path_length + ppl)
1605  * sizeof(struct GNUNET_DHT_PathElement);
1606  if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1607  (get_path_length >
1608  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1609  (ppl >
1610  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1612  {
1613  ppl = 0;
1614  get_path_length = 0;
1615  msize = bd->data_size + (get_path_length + ppl)
1616  * sizeof(struct GNUNET_DHT_PathElement);
1617  }
1618  if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1619  (get_path_length >
1620  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1621  (ppl >
1622  GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1624  {
1625  GNUNET_break (0);
1626  return false;
1627  }
1629  "Forwarding reply for key %s to peer %s\n",
1630  GNUNET_h2s (query_hash),
1631  GNUNET_i2s (&pi->id));
1633  "# RESULT messages queued for transmission",
1634  1,
1635  GNUNET_NO);
1636  {
1637  struct PeerResultMessage *prm;
1638  char buf[sizeof (*prm) + msize] GNUNET_ALIGN;
1639 
1640  prm = (struct PeerResultMessage *) buf;
1642  prm->header.size = htons (sizeof (buf));
1643  prm->type = htonl (bd->type);
1644  prm->reserved = htonl (0);
1645  prm->put_path_length = htons (ppl);
1646  prm->get_path_length = htons (get_path_length);
1648  prm->key = *query_hash;
1649  paths = (struct GNUNET_DHT_PathElement *) &prm[1];
1650  if (NULL != bd->put_path)
1651  {
1652  GNUNET_memcpy (paths,
1653  bd->put_path,
1654  ppl * sizeof(struct GNUNET_DHT_PathElement));
1655  }
1656  else
1657  {
1658  GNUNET_assert (0 == ppl);
1659  }
1660  if (NULL != get_path)
1661  {
1662  GNUNET_memcpy (&paths[ppl],
1663  get_path,
1664  get_path_length * sizeof(struct GNUNET_DHT_PathElement));
1665  }
1666  else
1667  {
1668  GNUNET_assert (0 == get_path_length);
1669  }
1670  /* 0 == get_path_length+ppl means path is not being tracked */
1671  if (0 != (get_path_length + ppl))
1672  {
1673  /* Note that the last signature in 'paths' was not initialized before,
1674  so this is crucial to avoid sending garbage. */
1675  sign_path (bd->data,
1676  bd->data_size,
1677  bd->expiration_time,
1678  &paths[ppl + get_path_length - 1].pred,
1679  &pi->id,
1680  &paths[ppl + get_path_length - 1].sig);
1682  "Signing GET PATH %u/%u of %s => %s\n",
1683  ppl,
1684  get_path_length,
1685  GNUNET_h2s (query_hash),
1686  GNUNET_B2S (&paths[ppl + get_path_length - 1].sig));
1687  }
1688  GNUNET_memcpy (&paths[ppl + get_path_length],
1689  bd->data,
1690  bd->data_size);
1691 
1692 #if SANITY_CHECKS > 1
1693  {
1694  struct GNUNET_DHT_PathElement xpaths[get_path_length + 1];
1695 
1696  memcpy (xpaths,
1697  &paths[ppl],
1698  get_path_length * sizeof (struct GNUNET_DHT_PathElement));
1699  xpaths[get_path_length].pred = GDS_my_identity;
1700  if (0 !=
1702  bd->data_size,
1703  bd->expiration_time,
1704  paths,
1705  ppl,
1706  xpaths,
1707  get_path_length + 1,
1708  &pi->id))
1709  {
1710  GNUNET_break (0);
1711  return false;
1712  }
1713  }
1714 #endif
1715  do_send (pi,
1716  &prm->header);
1717  }
1718  return true;
1719 }
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
Data is returned to peer from DHT.
uint16_t get_path_length
Length of the GET path that follows (if tracked).
struct GNUNET_HashCode key
The key of the corresponding GET request.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT.
uint16_t put_path_length
Length of the PUT path that follows (if tracked).
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?

Referenced by check_dht_p2p_get(), handle_find_local_hello(), and handle_find_my_hello().

Here is the caller graph for this function:

◆ GDS_am_closest_peer()

enum GNUNET_GenericReturnValue 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 888 of file gnunet-service-dht_neighbours.c.

946 {
948  key))
949  return GNUNET_YES;
950  for (int bucket_num = find_bucket (key);
951  bucket_num < closest_bucket;
952  bucket_num++)
953  {
954  unsigned int count = 0;
955 
956  GNUNET_assert (bucket_num >= 0);
957  for (struct PeerInfo *pos = k_buckets[bucket_num].head;
958  NULL != pos;
959  pos = pos->next)
960  {
961  if (count >= bucket_size)
962  break; /* we only consider first #bucket_size entries per bucket */
963  count++;
964  if ( (NULL != bloom) &&
965  (GNUNET_YES ==
967  &pos->phash)) )
968  continue; /* Ignore filtered peers */
969  /* All peers in this bucket must be closer than us, as
970  they mismatch with our PID on the pivotal bit. So
971  because an unfiltered peer exists, we are not the
972  closest. */
973  int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash,
975  key);
976  switch (delta)
977  {
978  case -1: /* pos closer */
979  return GNUNET_NO;
980  case 0: /* identical, impossible! */
981  GNUNET_assert (0);
982  break;
983  case 1: /* I am closer */
984  break;
985  }
986  }
987  }
988  /* No closer (unfiltered) peers found; we must be the closest! */
989  return GNUNET_YES;
990 }
static struct PendingResolutions * head
Head of list of pending resolution requests.
Definition: gnunet-ats.c:230
static int find_bucket(const struct GNUNET_HashCode *hc)
Find the optimal bucket for this key.
static unsigned int bucket_size
Maximum size for each bucket.
static unsigned int closest_bucket
The lowest currently used bucket, initially 0 (for 0-bits matching bucket).
static struct PeerBucket k_buckets[sizeof(struct GNUNET_HashCode) *8]
The buckets.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_CRYPTO_hash_xorcmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2, const struct GNUNET_HashCode *target)
Find out which of the two GNUNET_CRYPTO_hash codes is closer to target in the XOR metric (Kademlia).
Definition: crypto_hash.c:242
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
struct PendingResolutions * next
Kept in a DLL.
Definition: gnunet-ats.c:159

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

Referenced by handle_dht_local_put(), 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:

◆ GDS_try_connect()

void GDS_try_connect ( void *  cls,
const char *  uri 
)

Callback function used to extract URIs from a builder.

Called when we should consider connecting to a peer.

Parameters
clsclosure pointing to a struct GNUNET_PeerIdentity *
urione of the URIs

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

2587 {
2588  const struct GNUNET_PeerIdentity *pid = cls;
2589  struct GNUNET_HashCode phash;
2590  int peer_bucket;
2591  struct PeerBucket *bucket;
2592 
2593  if (0 == GNUNET_memcmp (&GDS_my_identity,
2594  pid))
2595  {
2597  "Got a HELLO for my own PID, ignoring it\n");
2598  return; /* that's us! */
2599  }
2601  sizeof(*pid),
2602  &phash);
2603  peer_bucket = find_bucket (&phash);
2604  GNUNET_assert ( (peer_bucket >= 0) &&
2605  ((unsigned int) peer_bucket < MAX_BUCKETS));
2606  bucket = &k_buckets[peer_bucket];
2607  if (bucket->peers_size >= bucket_size)
2608  return; /* do not care */
2609  for (struct PeerInfo *pi = bucket->head;
2610  NULL != pi;
2611  pi = pi->next)
2612  if (0 ==
2613  GNUNET_memcmp (&pi->id,
2614  pid))
2615  {
2616  /* already connected */
2617  /* TODO: maybe consider 'uri' anyway as an additional
2618  alternative address??? */
2619  return;
2620  }
2622  "Discovered peer %s at %s suitable for bucket %d (%u/%u), trying to connect\n",
2623  GNUNET_i2s (pid),
2624  uri,
2625  peer_bucket,
2626  bucket->peers_size,
2627  bucket_size);
2628  /* new peer that we like! */
2630  uri);
2631 }
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
void GDS_u_try_connect(const struct GNUNET_PeerIdentity *pid, const char *address)
Ask all underlays to connect to peer pid at address.
#define MAX_BUCKETS
How many buckets will we allow in total.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
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
@ GNUNET_ERROR_TYPE_INFO
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
Peers are grouped into buckets.
struct PeerInfo * head
Head of DLL.
unsigned int peers_size
Number of peers in the bucket.

References bucket_size, find_bucket(), GDS_my_identity, GDS_u_try_connect(), GNUNET_assert, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, PeerBucket::head, k_buckets, MAX_BUCKETS, PeerBucket::peers_size, pi, pid, and uri.

Referenced by GDS_NEIGHBOURS_handle_get(), and handle_dht_local_hello_offer().

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

◆ GDS_u_connect()

void GDS_u_connect ( void *  cls,
struct GNUNET_DHTU_Target target,
const struct GNUNET_PeerIdentity pid,
void **  ctx 
)

Function to call when we connect to a peer and can henceforth transmit to that peer.

Parameters
clsthe closure, must be a struct GDS_Underlay
targethandle to the target, pointer will remain valid until disconnect_cb is called @para pid peer identity, pointer will remain valid until disconnect_cb is called
[out]ctxstorage space for DHT to use in association with this target

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

738 {
739  struct GDS_Underlay *u = cls;
740  struct PeerInfo *pi;
741  struct PeerBucket *bucket;
742  bool do_hold = false;
743 
744  /* Check for connect to self message */
745  if (0 == GNUNET_memcmp (&GDS_my_identity,
746  pid))
747  return;
749  "Connected to peer %s\n",
750  GNUNET_i2s (pid));
752  pid);
753  if (NULL == pi)
754  {
756  "# peers connected",
757  1,
758  GNUNET_NO);
759  pi = GNUNET_new (struct PeerInfo);
760  pi->id = *pid;
762  sizeof(*pid),
763  &pi->phash);
764  pi->peer_bucket = find_bucket (&pi->phash);
765  GNUNET_assert ( (pi->peer_bucket >= 0) &&
766  ((unsigned int) pi->peer_bucket < MAX_BUCKETS));
767  bucket = &k_buckets[pi->peer_bucket];
769  bucket->tail,
770  pi);
771  bucket->peers_size++;
773  (unsigned int) pi->peer_bucket + 1);
776  &pi->id,
777  pi,
779  if (bucket->peers_size <= bucket_size)
780  {
782  do_hold = true;
783  }
786  {
787  /* got a first connection, good time to start with FIND PEER requests... */
788  GNUNET_assert (NULL == find_peer_task);
790  NULL);
791  }
792  }
793  {
794  struct Target *t;
795 
796  t = GNUNET_new (struct Target);
797  t->u = u;
798  t->utarget = target;
799  t->pi = pi;
801  pi->t_tail,
802  t);
803  *ctx = t;
804 
805  }
806  if (do_hold)
807  update_hold (bucket);
808 }
static void send_find_peer_message(void *cls)
Task to send a find peer message for our own peer identifier so that we can find the closest peers in...
static int disable_try_connect
Option for testing that disables the 'connect' function of the DHT.
static unsigned int newly_found_peers
How many peers have we added since we sent out our last find peer request?
static struct GNUNET_SCHEDULER_Task * find_peer_task
Task that sends FIND PEER requests.
static void update_hold(struct PeerBucket *bucket)
The list of the first bucket_size peers of bucket changed.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_MAX(a, b)
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head 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.
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_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:1281
Information we keep per underlay.
struct PeerInfo * tail
Tail of DLL.
List of targets that we can use to reach this peer.
struct GDS_Underlay * u
Underlay providing this target.

References all_connected_peers, bucket_size, closest_bucket, ctx, disable_try_connect, find_bucket(), find_peer_task, GDS_my_identity, GDS_stats, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, 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, newly_found_peers, PeerBucket::peers_size, pi, pid, send_find_peer_message(), t, PeerBucket::tail, Target::u, and update_hold().

Referenced by load_underlay().

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

◆ GDS_u_disconnect()

void GDS_u_disconnect ( void *  ctx)

Function to call when we disconnected from a peer and can henceforth cannot transmit to that peer anymore.

Parameters
[in]ctxstorage space used by the DHT in association with this target

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

813 {
814  struct Target *t = ctx;
815  struct PeerInfo *pi;
816  struct PeerBucket *bucket;
817  bool was_held = false;
818 
819  /* Check for disconnect from self message (on shutdown) */
820  if (NULL == t)
821  return;
822  pi = t->pi;
824  pi->t_tail,
825  t);
826  if (NULL != t->ph)
827  {
828  GDS_u_drop (t->u,
829  t->ph);
830  t->ph = NULL;
831  was_held = true;
832  }
833  if (t->load > 0)
834  {
835  t->dropped = true;
836  t->pi = NULL;
837  }
838  else
839  {
840  GNUNET_free (t);
841  }
842  if (NULL != pi->t_head)
843  return; /* got other connections still */
845  "Disconnected from peer %s\n",
846  GNUNET_i2s (&pi->id));
848  "# peers connected",
849  -1,
850  GNUNET_NO);
853  &pi->id,
854  pi));
857  {
859  find_peer_task = NULL;
860  }
861  GNUNET_assert (pi->peer_bucket >= 0);
862  bucket = &k_buckets[pi->peer_bucket];
864  bucket->tail,
865  pi);
866  GNUNET_assert (bucket->peers_size > 0);
867  bucket->peers_size--;
868  if ( (was_held) &&
869  (bucket->peers_size >= bucket_size - 1) )
870  update_hold (bucket);
871  while ( (closest_bucket > 0) &&
872  (0 == k_buckets[closest_bucket - 1].peers_size))
873  closest_bucket--;
874  GNUNET_free (pi->hello);
875  GNUNET_free (pi);
876 }
void GDS_u_drop(struct GDS_Underlay *u, struct GNUNET_DHTU_PreferenceHandle *ph)
Drop a hold ph from underlay u.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957

References all_connected_peers, bucket_size, closest_bucket, ctx, disable_try_connect, find_peer_task, GDS_stats, GDS_u_drop(), 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, PeerBucket::peers_size, pi, t, PeerBucket::tail, and update_hold().

Referenced by load_underlay().

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

◆ GDS_u_receive()

void GDS_u_receive ( void *  cls,
void **  tctx,
void **  sctx,
const void *  message,
size_t  message_size 
)

Function to call when we receive a message.

Parameters
clsthe closure
originwhere the message originated from
[in,out]tctxctx of target address where we received the message from
[in,out]sctxctx of our own source address at which we received the message
messagethe message we received
message_sizenumber of bytes in message

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

2521 {
2522  struct Target *t = *tctx;
2523  struct GNUNET_MQ_MessageHandler core_handlers[] = {
2524  GNUNET_MQ_hd_var_size (dht_p2p_get,
2526  struct PeerGetMessage,
2527  t),
2528  GNUNET_MQ_hd_var_size (dht_p2p_put,
2530  struct PeerPutMessage,
2531  t),
2532  GNUNET_MQ_hd_var_size (dht_p2p_result,
2534  struct PeerResultMessage,
2535  t),
2536  GNUNET_MQ_hd_var_size (dht_p2p_hello,
2538  struct GNUNET_MessageHeader,
2539  t),
2541  };
2542  const struct GNUNET_MessageHeader *mh = message;
2543 
2544  (void) cls; /* the 'struct GDS_Underlay' */
2545  (void) sctx; /* our receiver address */
2546  if (NULL == t)
2547  {
2548  /* Received message claiming to originate from myself?
2549  Ignore! */
2550  GNUNET_break_op (0);
2551  return;
2552  }
2553  if (message_size < sizeof (*mh))
2554  {
2555  GNUNET_break_op (0);
2556  return;
2557  }
2558  if (message_size != ntohs (mh->size))
2559  {
2560  GNUNET_break_op (0);
2561  return;
2562  }
2564  "Handling message of type %u from peer %s\n",
2565  ntohs (mh->type),
2566  GNUNET_i2s (&t->pi->id));
2567  if (GNUNET_OK !=
2568  GNUNET_MQ_handle_message (core_handlers,
2569  mh))
2570  {
2571  GNUNET_break_op (0);
2572  return;
2573  }
2574 }
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
int GNUNET_MQ_handle_message(const struct GNUNET_MQ_MessageHandler *handlers, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given h...
Definition: mq.c:203
#define GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO
HELLO advertising a neighbours addresses.
Message handler for a specific message type.
Header for all communications.

References GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, GNUNET_MQ_handle_message(), GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_OK, mh, and t.

Referenced by load_underlay().

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

◆ GDS_NEIGHBOURS_broadcast()

void GDS_NEIGHBOURS_broadcast ( const struct GNUNET_MessageHeader msg)

Send msg to all peers in our buckets.

Parameters
msgmessage to broadcast

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

2641 {
2642  for (unsigned int bc = 0; bc<closest_bucket; bc++)
2643  {
2644  struct PeerBucket *bucket = &k_buckets[bc];
2645  unsigned int count = 0;
2646 
2647  for (struct PeerInfo *pos = bucket->head;
2648  NULL != pos;
2649  pos = pos->next)
2650  {
2651  if (count >= bucket_size)
2652  break; /* we only consider first #bucket_size entries per bucket */
2653  count++;
2654  do_send (pos,
2655  msg);
2656  }
2657  }
2658 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct PeerInfo * next
Next peer entry (DLL)

References bucket_size, closest_bucket, do_send(), PeerBucket::head, k_buckets, msg, and PeerInfo::next.

Referenced by broadcast_hello().

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

◆ GDS_NEIGHBOURS_init()

enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_init ( void  )

Initialize neighbours subsystem.

Returns
GNUNET_OK on success, GNUNET_SYSERR on error

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

2663 {
2664 
2665  unsigned long long temp_config_num;
2666 
2669  "DHT",
2670  "DISABLE_TRY_CONNECT");
2671  if (GNUNET_OK ==
2673  "DHT",
2674  "bucket_size",
2675  &temp_config_num))
2676  bucket_size = (unsigned int) temp_config_num;
2679  "DHT",
2680  "CACHE_RESULTS");
2682  GNUNET_YES);
2683  return GNUNET_OK;
2684 }
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
Configuration we use.
static int cache_results
Do we cache all results that we are routing in the local datacache?
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_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).

Referenced by run().

Here is the caller graph for this function:

◆ GDS_NEIGHBOURS_done()

void GDS_NEIGHBOURS_done ( void  )

Shutdown neighbours subsystem.

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

2689 {
2690  if (NULL == all_connected_peers)
2691  return;
2692  GNUNET_assert (0 ==
2695  all_connected_peers = NULL;
2696  GNUNET_assert (NULL == find_peer_task);
2697 }
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.

References all_connected_peers, find_peer_task, GNUNET_assert, GNUNET_CONTAINER_multipeermap_destroy(), and GNUNET_CONTAINER_multipeermap_size().

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

2702 {
2703  return &GDS_my_identity;
2704 }