GNUnet  0.17.6
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 GNUNET_DATACACHE_Block *bd, 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 GNUNET_DATACACHE_Block *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 1665 of file gnunet-service-dht_neighbours.c.

1666 {
1668  target);
1669 }
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 GNUNET_DATACACHE_Block bd,
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
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 1302 of file gnunet-service-dht_neighbours.c.

1326 {
1327  unsigned int target_count;
1328  struct PeerInfo **targets;
1329  size_t msize;
1330  unsigned int skip_count;
1331  enum GNUNET_DHT_RouteOption ro = bd->ro;
1332  unsigned int put_path_length = bd->put_path_length;
1333  const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
1334  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1335  bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1336  const struct GNUNET_PeerIdentity *trunc_peer
1337  = truncated
1338  ? &bd->trunc_peer
1339  : NULL;
1340 
1341 #if SANITY_CHECKS > 1
1342  unsigned int failure_offset;
1343 
1344  failure_offset
1346  bd->data_size,
1347  bd->expiration_time,
1348  trunc_peer,
1349  put_path,
1350  put_path_length,
1351  NULL, 0, /* get_path */
1352  &GDS_my_identity);
1353  if (0 != failure_offset)
1354  {
1355  GNUNET_break_op (0);
1356  truncated = true;
1357  trunc_peer = &put_path[failure_offset - 1].pred;
1358  put_path = &put_path[failure_offset];
1359  put_path_length = put_path_length - failure_offset;
1361  }
1362 #endif
1364  "Adding myself (%s) to PUT bloomfilter for %s with RO(%s/%s)\n",
1366  GNUNET_h2s (&bd->key),
1367  (bd->ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-",
1368  (bd->ro & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1369 
1370  /* if we got a HELLO, consider it for our own routing table */
1371  hello_check (bd);
1372  GNUNET_assert (NULL != bf);
1376  "# PUT requests routed",
1377  1,
1378  GNUNET_NO);
1379  if (bd->data_size
1381  - sizeof(struct PeerPutMessage))
1382  {
1383  GNUNET_break (0);
1384  return GNUNET_SYSERR;
1385  }
1386  msize = bd->data_size + sizeof(struct PeerPutMessage);
1387  if (tracking)
1388  {
1389  if (msize + sizeof (struct GNUNET_CRYPTO_EddsaSignature)
1391  {
1393  "Discarding message that is too large due to tracking\n");
1394  return GNUNET_NO;
1395  }
1396  msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
1397  }
1398  else
1399  {
1400  /* If tracking is disabled, also discard any path we might have
1401  gotten from some broken peer */
1402  GNUNET_break_op (0 == put_path_length);
1403  put_path_length = 0;
1404  }
1405  if (truncated)
1406  msize += sizeof (struct GNUNET_PeerIdentity);
1407  if (msize + put_path_length * sizeof(struct GNUNET_DHT_PathElement)
1409  {
1410  unsigned int mlen;
1411  unsigned int ppl;
1412 
1414  "Truncating path that is too large due\n");
1416  if (! truncated)
1417  {
1418  /* We need extra space for the truncation, consider that,
1419  too! */
1420  truncated = true;
1421  mlen -= sizeof (struct GNUNET_PeerIdentity);
1422  msize += sizeof (struct GNUNET_PeerIdentity);
1423  }
1424  /* compute maximum length of path we can keep */
1425  ppl = mlen / sizeof (struct GNUNET_DHT_PathElement);
1426  GNUNET_assert (put_path_length - ppl > 0);
1427  trunc_peer = &put_path[put_path_length - ppl - 1].pred;
1428  put_path = &put_path[put_path_length - ppl];
1429  put_path_length = ppl;
1431  }
1432  else
1433  {
1434  msize += bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement);
1435  }
1436  target_count
1437  = get_target_peers (&bd->key,
1438  bf,
1439  hop_count,
1440  desired_replication_level,
1441  &targets);
1442  if (0 == target_count)
1443  {
1445  "Routing PUT for %s terminates after %u hops at %s\n",
1446  GNUNET_h2s (&bd->key),
1447  (unsigned int) hop_count,
1449  return GNUNET_NO;
1450  }
1451  skip_count = 0;
1452  for (unsigned int i = 0; i < target_count; i++)
1453  {
1454  struct PeerInfo *target = targets[i];
1455  struct PeerPutMessage *ppm;
1456  char buf[msize] GNUNET_ALIGN;
1457  struct GNUNET_DHT_PathElement *pp;
1458  void *data;
1459 
1461  "Routing PUT for %s after %u hops to %s\n",
1462  GNUNET_h2s (&bd->key),
1463  (unsigned int) hop_count,
1464  GNUNET_i2s (&target->id));
1465  ppm = (struct PeerPutMessage *) buf;
1467  ppm->header.size = htons (sizeof (buf));
1468  ppm->type = htonl (bd->type);
1469  ppm->options = htons (ro);
1470  ppm->hop_count = htons (hop_count + 1);
1472  ppm->put_path_length = htons (put_path_length);
1476  &target->phash));
1479  ppm->bloomfilter,
1480  DHT_BLOOM_SIZE));
1481  ppm->key = bd->key;
1482  if (truncated)
1483  {
1484  void *tgt = &ppm[1];
1485 
1486  GNUNET_memcpy (tgt,
1487  trunc_peer,
1488  sizeof (struct GNUNET_PeerIdentity));
1489  pp = (struct GNUNET_DHT_PathElement *)
1490  (tgt + sizeof (struct GNUNET_PeerIdentity));
1491  }
1492  else
1493  {
1494  pp = (struct GNUNET_DHT_PathElement *) &ppm[1];
1495  }
1496  GNUNET_memcpy (pp,
1497  put_path,
1498  sizeof (struct GNUNET_DHT_PathElement) * put_path_length);
1499  if (tracking)
1500  {
1501  void *tgt = &pp[put_path_length];
1502  struct GNUNET_CRYPTO_EddsaSignature last_sig;
1503 
1504  if (0 == put_path_length)
1505  {
1506  /* Note that the signature in 'put_path' was not initialized before,
1507  so this is crucial to avoid sending garbage. */
1508  sign_path (bd->data,
1509  bd->data_size,
1510  bd->expiration_time,
1511  trunc_peer,
1512  &target->id,
1513  &last_sig);
1514  }
1515  else
1516  {
1517  sign_path (bd->data,
1518  bd->data_size,
1519  bd->expiration_time,
1520  &pp[put_path_length - 1].pred,
1521  &target->id,
1522  &last_sig);
1523  }
1525  "Signing PUT PATH %u => %s\n",
1526  put_path_length,
1527  GNUNET_B2S (&last_sig));
1528  memcpy (tgt,
1529  &last_sig,
1530  sizeof (last_sig));
1531  data = tgt + sizeof (last_sig);
1532  }
1533  else /* ! tracking */
1534  {
1535  data = &ppm[1];
1536  }
1538  bd->data,
1539  bd->data_size);
1540  do_send (target,
1541  &ppm->header);
1542  }
1543  GNUNET_free (targets);
1545  "# PUT messages queued for transmission",
1546  target_count - skip_count,
1547  GNUNET_NO);
1548  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1549 }
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
uint32_t data
The data value.
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 hello_check(const struct GNUNET_DATACACHE_Block *bd)
If we got a HELLO, consider it for our own routing table.
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 char buf[2048]
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.
bool 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...
GNUNET_DHT_RouteOption
Options for routing.
unsigned int GNUNET_DHT_verify_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_PeerIdentity *bpid, 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:1353
@ GNUNET_DHT_RO_TRUNCATED
Flag set if the path was truncated.
@ 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_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:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#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
an ECC signature using EdDSA.
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.
const void * data
Actual block data.
enum GNUNET_DHT_RouteOption ro
Options for routing for the block.
struct GNUNET_PeerIdentity trunc_peer
If the path was truncated, this is the peer ID at which the path was truncated.
struct GNUNET_HashCode key
Key of the block.
size_t data_size
Number of bytes in data.
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
struct GNUNET_PeerIdentity pred
Previous peer on the path (matches "pred" in the signed field).
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.
The identity of the host (wraps the signing key of the peer).
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 1302 of file gnunet-service-dht_neighbours.c.

1562 {
1563  unsigned int target_count;
1564  struct PeerInfo **targets;
1565  size_t msize;
1566  size_t result_filter_size;
1567  void *result_filter;
1568  unsigned int skip_count;
1569 
1570  GNUNET_assert (NULL != peer_bf);
1572  "# GET requests routed",
1573  1,
1574  GNUNET_NO);
1575  target_count = get_target_peers (key,
1576  peer_bf,
1577  hop_count,
1578  desired_replication_level,
1579  &targets);
1581  "Adding myself (%s) to GET bloomfilter for %s with RO(%s/%s)\n",
1583  GNUNET_h2s (key),
1585  (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1586 
1589  if (0 == target_count)
1590  {
1592  "Routing GET for %s terminates after %u hops at %s\n",
1593  GNUNET_h2s (key),
1594  (unsigned int) hop_count,
1596  return GNUNET_NO;
1597  }
1598  if (GNUNET_OK !=
1600  &result_filter,
1601  &result_filter_size))
1602  {
1603  result_filter = NULL;
1604  result_filter_size = 0;
1605  }
1606  msize = xquery_size + result_filter_size;
1607  if (msize + sizeof(struct PeerGetMessage) >= GNUNET_MAX_MESSAGE_SIZE)
1608  {
1609  GNUNET_break (0);
1610  GNUNET_free (result_filter);
1611  GNUNET_free (targets);
1612  return GNUNET_NO;
1613  }
1614  /* forward request */
1615  skip_count = 0;
1616  for (unsigned int i = 0; i < target_count; i++)
1617  {
1618  struct PeerInfo *target = targets[i];
1619  struct PeerGetMessage *pgm;
1620  char buf[sizeof (*pgm) + msize] GNUNET_ALIGN;
1621  char *rf;
1622 
1624  "Routing GET for %s after %u hops to %s\n",
1625  GNUNET_h2s (key),
1626  (unsigned int) hop_count,
1627  GNUNET_i2s (&target->id));
1628  pgm = (struct PeerGetMessage *) buf;
1630  pgm->header.size = htons (sizeof (buf));
1631  pgm->type = htonl (type);
1632  pgm->options = htons (options);
1633  pgm->hop_count = htons (hop_count + 1);
1635  pgm->result_filter_size = htons ((uint16_t) result_filter_size);
1638  &target->phash));
1641  pgm->bloomfilter,
1642  DHT_BLOOM_SIZE));
1643  pgm->key = *key;
1644  rf = (char *) &pgm[1];
1645  GNUNET_memcpy (rf,
1646  result_filter,
1649  xquery,
1650  xquery_size);
1651  do_send (target,
1652  &pgm->header);
1653  }
1655  "# GET messages queued for transmission",
1656  target_count - skip_count,
1657  GNUNET_NO);
1658  GNUNET_free (targets);
1659  GNUNET_free (result_filter);
1660  return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1661 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
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, void **raw_data, size_t *raw_data_size)
Serialize state of a block group.
Definition: block.c:175
#define GNUNET_MESSAGE_TYPE_DHT_P2P_GET
Peer tries to find data in DHT.
uint16_t result_filter_size
Size of the result filter.
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 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 GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::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 GNUNET_DATACACHE_Block::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 GNUNET_DATACACHE_Block 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 1673 of file gnunet-service-dht_neighbours.c.

1678 {
1679  struct GNUNET_DHT_PathElement *paths;
1680  size_t msize;
1681  unsigned int ppl = bd->put_path_length;
1682  const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
1683  enum GNUNET_DHT_RouteOption ro = bd->ro;
1684  bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1685  const struct GNUNET_PeerIdentity *trunc_peer
1686  = truncated
1687  ? &bd->trunc_peer
1688  : NULL;
1689  bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1690 #if SANITY_CHECKS > 1
1691  unsigned int failure_offset;
1692 
1693  failure_offset
1695  bd->data_size,
1696  bd->expiration_time,
1697  trunc_peer,
1698  put_path,
1699  ppl,
1700  get_path,
1701  get_path_length,
1702  &GDS_my_identity);
1703  if (0 != failure_offset)
1704  {
1705  GNUNET_assert (failure_offset <= ppl + get_path_length);
1706  GNUNET_break_op (0);
1707  if (failure_offset < ppl)
1708  {
1709  trunc_peer = &put_path[failure_offset - 1].pred;
1710  put_path += failure_offset;
1711  ppl -= failure_offset;
1712  truncated = true;
1714  }
1715  else
1716  {
1717  failure_offset -= ppl;
1718  if (0 == failure_offset)
1719  trunc_peer = &put_path[ppl - 1].pred;
1720  else
1721  trunc_peer = &get_path[failure_offset - 1].pred;
1722  ppl = 0;
1723  put_path = NULL;
1724  truncated = true;
1726  get_path += failure_offset;
1727  get_path_length -= failure_offset;
1728  }
1729  }
1730 #endif
1731  msize = bd->data_size + sizeof (struct PeerResultMessage);
1732  if (msize > GNUNET_MAX_MESSAGE_SIZE)
1733  {
1734  GNUNET_break_op (0);
1735  return false;
1736  }
1737  if (truncated)
1738  msize += sizeof (struct GNUNET_PeerIdentity);
1739  if (tracking)
1740  msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
1741  if (msize < bd->data_size)
1742  {
1743  GNUNET_break_op (0);
1744  return false;
1745  }
1746  if ( (GNUNET_MAX_MESSAGE_SIZE - msize)
1747  / sizeof(struct GNUNET_DHT_PathElement)
1748  < (get_path_length + ppl) )
1749  {
1750  get_path_length = 0;
1751  ppl = 0;
1752  }
1753  if ( (get_path_length > UINT16_MAX) ||
1754  (ppl > UINT16_MAX) )
1755  {
1756  GNUNET_break (0);
1757  get_path_length = 0;
1758  ppl = 0;
1759  }
1760  msize += (get_path_length + ppl)
1761  * sizeof(struct GNUNET_DHT_PathElement);
1763  "Forwarding reply for key %s to peer %s\n",
1764  GNUNET_h2s (query_hash),
1765  GNUNET_i2s (&pi->id));
1767  "# RESULT messages queued for transmission",
1768  1,
1769  GNUNET_NO);
1770  {
1771  struct PeerResultMessage *prm;
1772  char buf[msize] GNUNET_ALIGN;
1773  void *data;
1774 
1775  prm = (struct PeerResultMessage *) buf;
1777  prm->header.size = htons (sizeof (buf));
1778  prm->type = htonl ((uint32_t) bd->type);
1779  prm->reserved = htons (0);
1780  prm->options = htons ((uint16_t) ro);
1781  prm->put_path_length = htons ((uint16_t) ppl);
1782  prm->get_path_length = htons ((uint16_t) get_path_length);
1784  prm->key = *query_hash;
1785  if (truncated)
1786  {
1787  void *tgt = &prm[1];
1788 
1789  GNUNET_memcpy (tgt,
1790  trunc_peer,
1791  sizeof (struct GNUNET_PeerIdentity));
1792  paths = (struct GNUNET_DHT_PathElement *)
1793  (tgt + sizeof (struct GNUNET_PeerIdentity));
1794  }
1795  else
1796  {
1797  paths = (struct GNUNET_DHT_PathElement *) &prm[1];
1798  }
1799  if (NULL != put_path)
1800  {
1801  GNUNET_memcpy (paths,
1802  put_path,
1803  ppl * sizeof(struct GNUNET_DHT_PathElement));
1804  }
1805  else
1806  {
1807  GNUNET_assert (0 == ppl);
1808  }
1809  if (NULL != get_path)
1810  {
1811  GNUNET_memcpy (&paths[ppl],
1812  get_path,
1813  get_path_length * sizeof(struct GNUNET_DHT_PathElement));
1814  }
1815  else
1816  {
1817  GNUNET_assert (0 == get_path_length);
1818  }
1819  if (tracking)
1820  {
1821  struct GNUNET_CRYPTO_EddsaSignature sig;
1822  void *tgt = &paths[get_path_length + ppl];
1823  const struct GNUNET_PeerIdentity *pred;
1824 
1825  if (ppl + get_path_length > 0)
1826  pred = &paths[ppl + get_path_length - 1].pred;
1827  else if (truncated)
1828  pred = trunc_peer;
1829  else
1830  pred = NULL; /* we are first! */
1831  /* Note that the last signature in 'paths' was not initialized before,
1832  so this is crucial to avoid sending garbage. */
1833  sign_path (bd->data,
1834  bd->data_size,
1835  bd->expiration_time,
1836  pred,
1837  &pi->id,
1838  &sig);
1839  memcpy (tgt,
1840  &sig,
1841  sizeof (sig));
1842  data = tgt + sizeof (sig);
1844  "Signing GET PATH %u/%u of %s => %s\n",
1845  ppl,
1846  get_path_length,
1847  GNUNET_h2s (query_hash),
1848  GNUNET_B2S (&sig));
1849 #if SANITY_CHECKS > 1
1850  {
1851  struct GNUNET_DHT_PathElement xpaths[get_path_length + 1];
1852 
1853  memcpy (xpaths,
1854  &paths[ppl],
1855  get_path_length * sizeof (struct GNUNET_DHT_PathElement));
1856  xpaths[get_path_length].sig = sig;
1857  xpaths[get_path_length].pred = GDS_my_identity;
1858  if (0 !=
1860  bd->data_size,
1861  bd->expiration_time,
1862  trunc_peer,
1863  paths,
1864  ppl,
1865  xpaths,
1866  get_path_length + 1,
1867  &pi->id))
1868  {
1869  GNUNET_break (0);
1870  return false;
1871  }
1872  }
1873 #endif
1874  }
1875  else
1876  {
1877  data = &prm[1];
1878  }
1880  bd->data,
1881  bd->data_size);
1882  do_send (pi,
1883  &prm->header);
1884  }
1885  return true;
1886 }
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
Data is returned to peer from DHT.
struct GNUNET_CRYPTO_EddsaSignature sig
Signature affirming the hop of type GNUNET_SIGNATURE_PURPOSE_DHT_HOP.
uint16_t get_path_length
Length of the GET path that follows (if tracked).
uint16_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value in NBO.
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 895 of file gnunet-service-dht_neighbours.c.

953 {
955  key))
956  return GNUNET_YES;
957  for (int bucket_num = find_bucket (key);
958  bucket_num < closest_bucket;
959  bucket_num++)
960  {
961  unsigned int count = 0;
962 
963  GNUNET_assert (bucket_num >= 0);
964  for (struct PeerInfo *pos = k_buckets[bucket_num].head;
965  NULL != pos;
966  pos = pos->next)
967  {
968  if (count >= bucket_size)
969  break; /* we only consider first #bucket_size entries per bucket */
970  count++;
971  if ( (NULL != bloom) &&
972  (GNUNET_YES ==
974  &pos->phash)) )
975  continue; /* Ignore filtered peers */
976  /* All peers in this bucket must be closer than us, as
977  they mismatch with our PID on the pivotal bit. So
978  because an unfiltered peer exists, we are not the
979  closest. */
980  int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash,
982  key);
983  switch (delta)
984  {
985  case -1: /* pos closer */
986  return GNUNET_NO;
987  case 0: /* identical, impossible! */
988  GNUNET_assert (0);
989  break;
990  case 1: /* I am closer */
991  break;
992  }
993  }
994  }
995  /* No closer (unfiltered) peers found; we must be the closest! */
996  return GNUNET_YES;
997 }
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.
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
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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 2847 of file gnunet-service-dht_neighbours.c.

2849 {
2850  const struct GNUNET_PeerIdentity *pid = cls;
2851  struct GNUNET_HashCode phash;
2852  int peer_bucket;
2853  struct PeerBucket *bucket;
2854 
2855  if (0 == GNUNET_memcmp (&GDS_my_identity,
2856  pid))
2857  {
2859  "Got a HELLO for my own PID, ignoring it\n");
2860  return; /* that's us! */
2861  }
2863  sizeof(*pid),
2864  &phash);
2865  peer_bucket = find_bucket (&phash);
2866  GNUNET_assert ( (peer_bucket >= 0) &&
2867  ((unsigned int) peer_bucket < MAX_BUCKETS));
2868  bucket = &k_buckets[peer_bucket];
2869  if (bucket->peers_size >= bucket_size)
2870  return; /* do not care */
2871  for (struct PeerInfo *pi = bucket->head;
2872  NULL != pi;
2873  pi = pi->next)
2874  if (0 ==
2875  GNUNET_memcmp (&pi->id,
2876  pid))
2877  {
2878  /* already connected */
2879  /* TODO: maybe consider 'uri' anyway as an additional
2880  alternative address??? */
2881  return;
2882  }
2884  "Discovered peer %s at %s suitable for bucket %d (%u/%u), trying to connect\n",
2885  GNUNET_i2s (pid),
2886  uri,
2887  peer_bucket,
2888  bucket->peers_size,
2889  bucket_size);
2890  /* new peer that we like! */
2892  uri);
2893 }
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
A 512-bit hashcode.
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 741 of file gnunet-service-dht_neighbours.c.

745 {
746  struct GDS_Underlay *u = cls;
747  struct PeerInfo *pi;
748  struct PeerBucket *bucket;
749  bool do_hold = false;
750 
751  /* Check for connect to self message */
752  if (0 == GNUNET_memcmp (&GDS_my_identity,
753  pid))
754  return;
756  "Connected to peer %s\n",
757  GNUNET_i2s (pid));
759  pid);
760  if (NULL == pi)
761  {
763  "# peers connected",
764  1,
765  GNUNET_NO);
766  pi = GNUNET_new (struct PeerInfo);
767  pi->id = *pid;
769  sizeof(*pid),
770  &pi->phash);
771  pi->peer_bucket = find_bucket (&pi->phash);
772  GNUNET_assert ( (pi->peer_bucket >= 0) &&
773  ((unsigned int) pi->peer_bucket < MAX_BUCKETS));
774  bucket = &k_buckets[pi->peer_bucket];
776  bucket->tail,
777  pi);
778  bucket->peers_size++;
780  (unsigned int) pi->peer_bucket + 1);
783  &pi->id,
784  pi,
786  if (bucket->peers_size <= bucket_size)
787  {
789  do_hold = true;
790  }
793  {
794  /* got a first connection, good time to start with FIND PEER requests... */
795  GNUNET_assert (NULL == find_peer_task);
797  NULL);
798  }
799  }
800  {
801  struct Target *t;
802 
803  t = GNUNET_new (struct Target);
804  t->u = u;
805  t->utarget = target;
806  t->pi = pi;
808  pi->t_tail,
809  t);
810  *ctx = t;
811 
812  }
813  if (do_hold)
814  update_hold (bucket);
815 }
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_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_MAX(a, b)
#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 819 of file gnunet-service-dht_neighbours.c.

820 {
821  struct Target *t = ctx;
822  struct PeerInfo *pi;
823  struct PeerBucket *bucket;
824  bool was_held = false;
825 
826  /* Check for disconnect from self message (on shutdown) */
827  if (NULL == t)
828  return;
829  pi = t->pi;
831  pi->t_tail,
832  t);
833  if (NULL != t->ph)
834  {
835  GDS_u_drop (t->u,
836  t->ph);
837  t->ph = NULL;
838  was_held = true;
839  }
840  if (t->load > 0)
841  {
842  t->dropped = true;
843  t->pi = NULL;
844  }
845  else
846  {
847  GNUNET_free (t);
848  }
849  if (NULL != pi->t_head)
850  return; /* got other connections still */
852  "Disconnected from peer %s\n",
853  GNUNET_i2s (&pi->id));
855  "# peers connected",
856  -1,
857  GNUNET_NO);
860  &pi->id,
861  pi));
864  {
866  find_peer_task = NULL;
867  }
868  GNUNET_assert (pi->peer_bucket >= 0);
869  bucket = &k_buckets[pi->peer_bucket];
871  bucket->tail,
872  pi);
873  GNUNET_assert (bucket->peers_size > 0);
874  bucket->peers_size--;
875  if ( (was_held) &&
876  (bucket->peers_size >= bucket_size - 1) )
877  update_hold (bucket);
878  while ( (closest_bucket > 0) &&
879  (0 == k_buckets[closest_bucket - 1].peers_size))
880  closest_bucket--;
881  GNUNET_free (pi->hello);
882  GNUNET_free (pi);
883 }
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.
enum GNUNET_GenericReturnValue 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 2778 of file gnunet-service-dht_neighbours.c.

2783 {
2784  struct Target *t = *tctx;
2785  struct GNUNET_MQ_MessageHandler core_handlers[] = {
2786  GNUNET_MQ_hd_var_size (dht_p2p_get,
2788  struct PeerGetMessage,
2789  t),
2790  GNUNET_MQ_hd_var_size (dht_p2p_put,
2792  struct PeerPutMessage,
2793  t),
2794  GNUNET_MQ_hd_var_size (dht_p2p_result,
2796  struct PeerResultMessage,
2797  t),
2798  GNUNET_MQ_hd_var_size (dht_p2p_hello,
2800  struct GNUNET_MessageHeader,
2801  t),
2803  };
2804  const struct GNUNET_MessageHeader *mh = message;
2805 
2806  (void) cls; /* the 'struct GDS_Underlay' */
2807  (void) sctx; /* our receiver address */
2808  if (NULL == t)
2809  {
2810  /* Received message claiming to originate from myself?
2811  Ignore! */
2812  GNUNET_break_op (0);
2813  return;
2814  }
2815  if (message_size < sizeof (*mh))
2816  {
2817  GNUNET_break_op (0);
2818  return;
2819  }
2820  if (message_size != ntohs (mh->size))
2821  {
2822  GNUNET_break_op (0);
2823  return;
2824  }
2826  "Handling message of type %u from peer %s\n",
2827  ntohs (mh->type),
2828  GNUNET_i2s (&t->pi->id));
2829  if (GNUNET_OK !=
2830  GNUNET_MQ_handle_message (core_handlers,
2831  mh))
2832  {
2833  GNUNET_break_op (0);
2834  return;
2835  }
2836 }
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 2902 of file gnunet-service-dht_neighbours.c.

2903 {
2904  for (unsigned int bc = 0; bc<closest_bucket; bc++)
2905  {
2906  struct PeerBucket *bucket = &k_buckets[bc];
2907  unsigned int count = 0;
2908 
2909  for (struct PeerInfo *pos = bucket->head;
2910  NULL != pos;
2911  pos = pos->next)
2912  {
2913  if (count >= bucket_size)
2914  break; /* we only consider first #bucket_size entries per bucket */
2915  count++;
2916  do_send (pos,
2917  msg);
2918  }
2919  }
2920 }
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 2902 of file gnunet-service-dht_neighbours.c.

2925 {
2926 
2927  unsigned long long temp_config_num;
2928 
2931  "DHT",
2932  "DISABLE_TRY_CONNECT");
2933  if (GNUNET_OK ==
2935  "DHT",
2936  "bucket_size",
2937  &temp_config_num))
2938  bucket_size = (unsigned int) temp_config_num;
2941  "DHT",
2942  "CACHE_RESULTS");
2944  GNUNET_YES);
2945  return GNUNET_OK;
2946 }
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 2950 of file gnunet-service-dht_neighbours.c.

2951 {
2952  if (NULL == all_connected_peers)
2953  return;
2954  GNUNET_assert (0 ==
2957  all_connected_peers = NULL;
2958  GNUNET_assert (NULL == find_peer_task);
2959 }
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 2963 of file gnunet-service-dht_neighbours.c.

2964 {
2965  return &GDS_my_identity;
2966 }