GNUnet 0.21.1
gnunet-service-dht_neighbours.h File Reference

GNUnet DHT routing code. More...

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 struct GNUNET_PeerIdentity *pid, 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 1664 of file gnunet-service-dht_neighbours.c.

1665{
1667 target);
1668}
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().

Referenced by process().

Here is the call graph for this function:
Here is the caller 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 1321 of file gnunet-service-dht_neighbours.c.

1325{
1326 unsigned int target_count;
1327 struct PeerInfo **targets;
1328 size_t msize;
1329 unsigned int skip_count;
1330 enum GNUNET_DHT_RouteOption ro = bd->ro;
1331 unsigned int put_path_length = bd->put_path_length;
1332 const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
1333 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1334 bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1335 const struct GNUNET_PeerIdentity *trunc_peer
1336 = truncated
1337 ? &bd->trunc_peer
1338 : NULL;
1339
1340#if SANITY_CHECKS > 1
1341 unsigned int failure_offset;
1342
1343 failure_offset
1345 bd->data_size,
1346 bd->expiration_time,
1347 trunc_peer,
1348 put_path,
1349 put_path_length,
1350 NULL, 0, /* get_path */
1352 if (0 != failure_offset)
1353 {
1354 GNUNET_break_op (0);
1355 truncated = true;
1356 trunc_peer = &put_path[failure_offset - 1].pred;
1357 put_path = &put_path[failure_offset];
1358 put_path_length = put_path_length - failure_offset;
1360 }
1361#endif
1363 "Adding myself (%s) to PUT bloomfilter for %s with RO(%s/%s)\n",
1365 GNUNET_h2s (&bd->key),
1366 (bd->ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-",
1367 (bd->ro & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1368
1369 /* if we got a HELLO, consider it for our own routing table */
1370 hello_check (bd);
1371 GNUNET_assert (NULL != bf);
1375 "# PUT requests routed",
1376 1,
1377 GNUNET_NO);
1378 if (bd->data_size
1380 - sizeof(struct PeerPutMessage))
1381 {
1382 GNUNET_break (0);
1383 return GNUNET_SYSERR;
1384 }
1385 msize = bd->data_size + sizeof(struct PeerPutMessage);
1386 if (tracking)
1387 {
1388 if (msize + sizeof (struct GNUNET_CRYPTO_EddsaSignature)
1390 {
1392 "Discarding message that is too large due to tracking\n");
1393 return GNUNET_NO;
1394 }
1395 msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
1396 }
1397 else
1398 {
1399 /* If tracking is disabled, also discard any path we might have
1400 gotten from some broken peer */
1401 GNUNET_break_op (0 == put_path_length);
1402 put_path_length = 0;
1403 }
1404 if (truncated)
1405 msize += sizeof (struct GNUNET_PeerIdentity);
1406 if (msize + put_path_length * sizeof(struct GNUNET_DHT_PathElement)
1408 {
1409 unsigned int mlen;
1410 unsigned int ppl;
1411
1413 "Truncating path that is too large due\n");
1415 if (! truncated)
1416 {
1417 /* We need extra space for the truncation, consider that,
1418 too! */
1419 truncated = true;
1420 mlen -= sizeof (struct GNUNET_PeerIdentity);
1421 msize += sizeof (struct GNUNET_PeerIdentity);
1422 }
1423 /* compute maximum length of path we can keep */
1424 ppl = mlen / sizeof (struct GNUNET_DHT_PathElement);
1425 GNUNET_assert (put_path_length - ppl > 0);
1426 trunc_peer = &put_path[put_path_length - ppl - 1].pred;
1427 put_path = &put_path[put_path_length - ppl];
1428 put_path_length = ppl;
1430 }
1431 else
1432 {
1433 msize += bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement);
1434 }
1435 target_count
1436 = get_target_peers (&bd->key,
1437 bf,
1438 hop_count,
1439 desired_replication_level,
1440 &targets);
1441 if (0 == target_count)
1442 {
1444 "Routing PUT for %s terminates after %u hops at %s\n",
1445 GNUNET_h2s (&bd->key),
1446 (unsigned int) hop_count,
1448 return GNUNET_NO;
1449 }
1450 skip_count = 0;
1451 for (unsigned int i = 0; i < target_count; i++)
1452 {
1453 struct PeerInfo *target = targets[i];
1454 struct PeerPutMessage *ppm;
1455 char buf[msize] GNUNET_ALIGN;
1456 struct GNUNET_DHT_PathElement *pp;
1457 void *data;
1458
1460 "Routing PUT for %s after %u hops to %s\n",
1461 GNUNET_h2s (&bd->key),
1462 (unsigned int) hop_count,
1463 GNUNET_i2s (&target->id));
1464 ppm = (struct PeerPutMessage *) buf;
1466 ppm->header.size = htons (sizeof (buf));
1467 ppm->type = htonl (bd->type);
1468 ppm->options = htons (ro);
1469 ppm->hop_count = htons (hop_count + 1);
1471 ppm->put_path_length = htons (put_path_length);
1475 &target->phash));
1478 ppm->bloomfilter,
1480 ppm->key = bd->key;
1481 if (truncated)
1482 {
1483 void *tgt = &ppm[1];
1484
1485 GNUNET_memcpy (tgt,
1486 trunc_peer,
1487 sizeof (struct GNUNET_PeerIdentity));
1488 pp = (struct GNUNET_DHT_PathElement *)
1489 (tgt + sizeof (struct GNUNET_PeerIdentity));
1490 }
1491 else
1492 {
1493 pp = (struct GNUNET_DHT_PathElement *) &ppm[1];
1494 }
1495 GNUNET_memcpy (pp,
1496 put_path,
1497 sizeof (struct GNUNET_DHT_PathElement) * put_path_length);
1498 if (tracking)
1499 {
1500 void *tgt = &pp[put_path_length];
1501 struct GNUNET_CRYPTO_EddsaSignature last_sig;
1502
1503 if (0 == put_path_length)
1504 {
1505 /* Note that the signature in 'put_path' was not initialized before,
1506 so this is crucial to avoid sending garbage. */
1507 sign_path (bd->data,
1508 bd->data_size,
1509 bd->expiration_time,
1510 trunc_peer,
1511 &target->id,
1512 &last_sig);
1513 }
1514 else
1515 {
1516 sign_path (bd->data,
1517 bd->data_size,
1518 bd->expiration_time,
1519 &pp[put_path_length - 1].pred,
1520 &target->id,
1521 &last_sig);
1522 }
1524 "Signing PUT PATH %u => %s\n",
1525 put_path_length,
1526 GNUNET_B2S (&last_sig));
1527 memcpy (tgt,
1528 &last_sig,
1529 sizeof (last_sig));
1530 data = tgt + sizeof (last_sig);
1531 }
1532 else /* ! tracking */
1533 {
1534 data = &ppm[1];
1535 }
1537 bd->data,
1538 bd->data_size);
1539 do_send (target,
1540 &ppm->header);
1541 }
1542 GNUNET_free (targets);
1544 "# PUT messages queued for transmission",
1545 target_count - skip_count,
1546 GNUNET_NO);
1547 return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1548}
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
static char * data
The data to insert into the dht.
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.
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.
enum GNUNET_GenericReturnValue 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...
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 *trunc_peer, 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:1351
@ 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
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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:638
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, must not be zero.
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).

References PeerPutMessage::bloomfilter, data, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::data_size, PeerPutMessage::desired_replication_level, DHT_BLOOM_SIZE, do_send(), GNUNET_DATACACHE_Block::expiration_time, PeerPutMessage::expiration_time, GDS_my_identity, GDS_my_identity_hash, GDS_stats, get_target_peers(), GNUNET_ALIGN, GNUNET_assert, GNUNET_B2S, GNUNET_break, GNUNET_break_op, GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_bloomfilter_get_raw_data(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_DHT_RO_RECORD_ROUTE, GNUNET_DHT_RO_TRUNCATED, GNUNET_DHT_verify_path(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_hton(), GNUNET_YES, PeerPutMessage::header, hello_check(), PeerPutMessage::hop_count, PeerInfo::id, GNUNET_DATACACHE_Block::key, PeerPutMessage::key, PeerPutMessage::options, PeerInfo::phash, GNUNET_DHT_PathElement::pred, GNUNET_DATACACHE_Block::put_path, GNUNET_DATACACHE_Block::put_path_length, PeerPutMessage::put_path_length, GNUNET_DATACACHE_Block::ro, sign_path(), GNUNET_MessageHeader::size, GNUNET_DATACACHE_Block::trunc_peer, GNUNET_MessageHeader::type, GNUNET_DATACACHE_Block::type, and PeerPutMessage::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()

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

1561{
1562 unsigned int target_count;
1563 struct PeerInfo **targets;
1564 size_t msize;
1565 size_t result_filter_size;
1566 void *result_filter;
1567 unsigned int skip_count;
1568
1569 GNUNET_assert (NULL != peer_bf);
1571 "# GET requests routed",
1572 1,
1573 GNUNET_NO);
1574 target_count = get_target_peers (key,
1575 peer_bf,
1576 hop_count,
1577 desired_replication_level,
1578 &targets);
1580 "Adding myself (%s) to GET bloomfilter for %s with RO(%s/%s)\n",
1582 GNUNET_h2s (key),
1584 (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
1585
1588 if (0 == target_count)
1589 {
1591 "Routing GET for %s terminates after %u hops at %s\n",
1592 GNUNET_h2s (key),
1593 (unsigned int) hop_count,
1595 return GNUNET_NO;
1596 }
1597 if (GNUNET_OK !=
1599 &result_filter,
1600 &result_filter_size))
1601 {
1602 result_filter = NULL;
1603 result_filter_size = 0;
1604 }
1605 msize = xquery_size + result_filter_size;
1606 if (msize + sizeof(struct PeerGetMessage) >= GNUNET_MAX_MESSAGE_SIZE)
1607 {
1608 GNUNET_break (0);
1609 GNUNET_free (result_filter);
1610 GNUNET_free (targets);
1611 return GNUNET_NO;
1612 }
1613 /* forward request */
1614 skip_count = 0;
1615 for (unsigned int i = 0; i < target_count; i++)
1616 {
1617 struct PeerInfo *target = targets[i];
1618 struct PeerGetMessage *pgm;
1619 char buf[sizeof (*pgm) + msize] GNUNET_ALIGN;
1620 char *rf;
1621
1623 "Routing GET for %s after %u hops to %s\n",
1624 GNUNET_h2s (key),
1625 (unsigned int) hop_count,
1626 GNUNET_i2s (&target->id));
1627 pgm = (struct PeerGetMessage *) buf;
1629 pgm->header.size = htons (sizeof (buf));
1630 pgm->type = htonl (type);
1631 pgm->options = htons (options);
1632 pgm->hop_count = htons (hop_count + 1);
1634 pgm->result_filter_size = htons ((uint16_t) result_filter_size);
1637 &target->phash));
1640 pgm->bloomfilter,
1642 pgm->key = *key;
1643 rf = (char *) &pgm[1];
1644 GNUNET_memcpy (rf,
1645 result_filter,
1648 xquery,
1649 xquery_size);
1650 do_send (target,
1651 &pgm->header);
1652 }
1654 "# GET messages queued for transmission",
1655 target_count - skip_count,
1656 GNUNET_NO);
1657 GNUNET_free (targets);
1658 GNUNET_free (result_filter);
1659 return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO;
1660}
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_HashCode key
The key used in the DHT.
static uint32_t type
Type string converted to DNS type value.
#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.

References PeerGetMessage::bloomfilter, PeerGetMessage::desired_replication_level, DHT_BLOOM_SIZE, do_send(), GDS_my_identity, GDS_my_identity_hash, GDS_stats, get_target_peers(), GNUNET_ALIGN, GNUNET_assert, GNUNET_BLOCK_group_serialize(), GNUNET_break, GNUNET_CONTAINER_bloomfilter_add(), GNUNET_CONTAINER_bloomfilter_get_raw_data(), GNUNET_CONTAINER_bloomfilter_test(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_DHT_RO_RECORD_ROUTE, 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_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, PeerGetMessage::header, PeerGetMessage::hop_count, PeerInfo::id, key, PeerGetMessage::key, options, PeerGetMessage::options, PeerInfo::phash, PeerGetMessage::result_filter_size, GNUNET_MessageHeader::size, type, GNUNET_MessageHeader::type, and PeerGetMessage::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
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 1672 of file gnunet-service-dht_neighbours.c.

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

References data, GNUNET_DATACACHE_Block::data, data_size, GNUNET_DATACACHE_Block::data_size, do_send(), GNUNET_DATACACHE_Block::expiration_time, PeerResultMessage::expiration_time, GDS_my_identity, GDS_stats, PeerResultMessage::get_path_length, GNUNET_ALIGN, GNUNET_assert, GNUNET_B2S, GNUNET_break, GNUNET_break_op, GNUNET_DHT_RO_RECORD_ROUTE, GNUNET_DHT_RO_TRUNCATED, GNUNET_DHT_verify_path(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), PeerResultMessage::header, PeerInfo::id, PeerResultMessage::key, PeerResultMessage::options, GNUNET_DHT_PathElement::pred, GNUNET_DATACACHE_Block::put_path, GNUNET_DATACACHE_Block::put_path_length, PeerResultMessage::put_path_length, PeerResultMessage::reserved, GNUNET_DATACACHE_Block::ro, GNUNET_DHT_PathElement::sig, sign_path(), GNUNET_MessageHeader::size, GNUNET_DATACACHE_Block::trunc_peer, GNUNET_MessageHeader::type, GNUNET_DATACACHE_Block::type, and PeerResultMessage::type.

Referenced by handle_find_local_hello(), handle_find_my_hello(), handle_local_result(), and process().

Here is the call graph for this function:
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 950 of file gnunet-service-dht_neighbours.c.

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

References bucket_size, closest_bucket, delta, find_bucket(), GDS_my_identity_hash, GNUNET_assert, GNUNET_CONTAINER_bloomfilter_test(), GNUNET_CRYPTO_hash_xorcmp(), GNUNET_memcmp, GNUNET_NO, GNUNET_YES, PeerBucket::head, k_buckets, key, and PeerInfo::next.

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 struct GNUNET_PeerIdentity pid,
const char *  uri 
)

Callback function used to extract URIs from a builder.

Called when we should consider connecting to a peer.

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

Called when we should consider connecting to a peer.

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

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

2889{
2890 (void) cls;
2891 struct GNUNET_HashCode phash;
2892 int peer_bucket;
2893 struct PeerBucket *bucket;
2894
2895 if (0 == GNUNET_memcmp (&GDS_my_identity,
2896 pid))
2897 {
2899 "Got a HELLO for my own PID, ignoring it\n");
2900 return; /* that's us! */
2901 }
2903 sizeof(*pid),
2904 &phash);
2905 peer_bucket = find_bucket (&phash);
2906 GNUNET_assert ( (peer_bucket >= 0) &&
2907 ((unsigned int) peer_bucket < MAX_BUCKETS));
2908 bucket = &k_buckets[peer_bucket];
2909 for (struct PeerInfo *pi = bucket->head;
2910 NULL != pi;
2911 pi = pi->next)
2912 if (0 ==
2913 GNUNET_memcmp (&pi->id,
2914 pid))
2915 {
2916 /* already connected */
2918 uri);
2919 return;
2920 }
2921 if (bucket->peers_size >= bucket_size)
2922 return; /* do not care */
2924 "Discovered peer %s at %s suitable for bucket %d (%u/%u), trying to connect\n",
2925 GNUNET_i2s (pid),
2926 uri,
2927 peer_bucket,
2928 bucket->peers_size,
2929 bucket_size);
2930 /* new peer that we like! */
2932 uri);
2933}
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.
struct PeerInfo * next
Next peer entry (DLL)

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, PeerInfo::next, PeerBucket::peers_size, pid, and uri.

Referenced by handle_dht_local_hello_offer(), and hello_check().

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

744{
745 struct GDS_Underlay *u = cls;
746 struct PeerInfo *pi;
747 struct PeerBucket *bucket;
748 bool do_hold = false;
749
750 /* Check for connect to self message */
752 pid))
753 return;
755 "Connected to peer %s\n",
756 GNUNET_i2s (pid));
758 pid);
759 if (NULL == pi)
760 {
762 "# peers connected",
763 1,
764 GNUNET_NO);
765 pi = GNUNET_new (struct PeerInfo);
766 pi->id = *pid;
768 sizeof(*pid),
769 &pi->phash);
770 pi->peer_bucket = find_bucket (&pi->phash);
771 GNUNET_assert ( (pi->peer_bucket >= 0) &&
772 ((unsigned int) pi->peer_bucket < MAX_BUCKETS));
773 bucket = &k_buckets[pi->peer_bucket];
775 bucket->tail,
776 pi);
777 bucket->peers_size++;
779 (unsigned int) pi->peer_bucket + 1);
782 &pi->id,
783 pi,
785 if (bucket->peers_size <= bucket_size)
786 {
788 do_hold = true;
789 }
792 {
793 /* got a first connection, good time to start with FIND PEER requests... */
796 NULL);
797 }
798 }
799 {
800 struct Target *t;
801
802 t = GNUNET_new (struct Target);
803 t->u = u;
804 t->utarget = target;
805 t->pi = pi;
807 pi->t_tail,
808 t);
809 *ctx = t;
810
811 }
812 if (do_hold)
813 update_hold (bucket);
814}
static mp_limb_t u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static struct GNUNET_FS_Handle * ctx
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_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:1299
Information we keep per underlay.
struct PeerInfo * tail
Tail of DLL.
struct Target * t_tail
Tail of DLL of targets for this peer.
int peer_bucket
Which bucket is this peer in?
struct Target * t_head
Head of DLL of targets for this peer.
List of targets that we can use to reach this peer.
struct PeerInfo * pi
Peer this is a target for.

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, PeerInfo::id, k_buckets, MAX_BUCKETS, newly_found_peers, PeerInfo::peer_bucket, PeerBucket::peers_size, PeerInfo::phash, Target::pi, pid, send_find_peer_message(), t, PeerInfo::t_head, PeerInfo::t_tail, PeerBucket::tail, 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 818 of file gnunet-service-dht_neighbours.c.

819{
820 struct Target *t = ctx;
821 struct PeerInfo *pi;
822 struct PeerBucket *bucket;
823 bool was_held = false;
824
825 /* Check for disconnect from self message (on shutdown) */
826 if (NULL == t)
827 return;
828 pi = t->pi;
830 pi->t_tail,
831 t);
832 if (NULL != t->ph)
833 {
834 GDS_u_drop (t->u,
835 t->ph);
836 t->ph = NULL;
837 was_held = true;
838 }
839 if (t->load > 0)
840 {
841 t->dropped = true;
842 t->pi = NULL;
843 }
844 else
845 {
846 GNUNET_free (t);
847 }
848 if (NULL != pi->t_head)
849 return; /* got other connections still */
851 "Disconnected from peer %s\n",
852 GNUNET_i2s (&pi->id));
854 "# peers connected",
855 -1,
856 GNUNET_NO);
859 &pi->id,
860 pi));
863 {
865 find_peer_task = NULL;
866 }
867 GNUNET_assert (pi->peer_bucket >= 0);
868 bucket = &k_buckets[pi->peer_bucket];
870 bucket->tail,
871 pi);
872 GNUNET_assert (bucket->peers_size > 0);
873 bucket->peers_size--;
874 if ( (was_held) &&
875 (bucket->peers_size >= bucket_size - 1) )
876 update_hold (bucket);
877 while ( (closest_bucket > 0) &&
880 GNUNET_free (pi->hello);
881 GNUNET_free (pi);
882}
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:975
void * hello
Block with a HELLO of this peer.

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, PeerInfo::hello, PeerInfo::id, k_buckets, PeerInfo::peer_bucket, PeerBucket::peers_size, t, PeerInfo::t_head, PeerInfo::t_tail, 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
[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 2817 of file gnunet-service-dht_neighbours.c.

2822{
2823 struct Target *t = *tctx;
2824 struct GNUNET_MQ_MessageHandler core_handlers[] = {
2825 GNUNET_MQ_hd_var_size (dht_p2p_get,
2827 struct PeerGetMessage,
2828 t),
2829 GNUNET_MQ_hd_var_size (dht_p2p_put,
2831 struct PeerPutMessage,
2832 t),
2833 GNUNET_MQ_hd_var_size (dht_p2p_result,
2835 struct PeerResultMessage,
2836 t),
2837 GNUNET_MQ_hd_var_size (dht_p2p_hello,
2839 struct GNUNET_MessageHeader,
2840 t),
2842 };
2843 const struct GNUNET_MessageHeader *mh = message;
2844
2845 (void) cls; /* the 'struct GDS_Underlay' */
2846 (void) sctx; /* our receiver address */
2847 if (NULL == t)
2848 {
2849 /* Received message claiming to originate from myself?
2850 Ignore! */
2851 GNUNET_break_op (0);
2852 return;
2853 }
2854 if (message_size < sizeof (*mh))
2855 {
2856 GNUNET_break_op (0);
2857 return;
2858 }
2859 if (message_size != ntohs (mh->size))
2860 {
2861 GNUNET_break_op (0);
2862 return;
2863 }
2865 "Handling message of type %u from peer %s\n",
2866 ntohs (mh->type),
2867 GNUNET_i2s (&t->pi->id));
2868 if (GNUNET_OK !=
2869 GNUNET_MQ_handle_message (core_handlers,
2870 mh))
2871 {
2872 GNUNET_break_op (0);
2873 return;
2874 }
2875}
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)
enum GNUNET_GenericReturnValue 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:205
#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 2942 of file gnunet-service-dht_neighbours.c.

2943{
2944 for (unsigned int bc = 0; bc<closest_bucket; bc++)
2945 {
2946 struct PeerBucket *bucket = &k_buckets[bc];
2947 unsigned int count = 0;
2948
2949 for (struct PeerInfo *pos = bucket->head;
2950 NULL != pos;
2951 pos = pos->next)
2952 {
2953 if (count >= bucket_size)
2954 break; /* we only consider first #bucket_size entries per bucket */
2955 count++;
2956 do_send (pos,
2957 msg);
2958 }
2959 }
2960}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2

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

2965{
2966
2967 unsigned long long temp_config_num;
2968
2971 "DHT",
2972 "DISABLE_TRY_CONNECT");
2973 if (GNUNET_OK ==
2975 "DHT",
2976 "bucket_size",
2977 &temp_config_num))
2978 bucket_size = (unsigned int) temp_config_num;
2981 "DHT",
2982 "CACHE_RESULTS");
2984 GNUNET_YES);
2985 return GNUNET_OK;
2986}
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).

References all_connected_peers, bucket_size, cache_results, disable_try_connect, GDS_cfg, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_OK, GNUNET_YES, and consensus-simulation::int.

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

2991{
2992 if (NULL == all_connected_peers)
2993 return;
2994 GNUNET_assert (0 ==
2997 all_connected_peers = NULL;
2998 GNUNET_assert (NULL == find_peer_task);
2999}
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 3003 of file gnunet-service-dht_neighbours.c.

3004{
3005 return &GDS_my_identity;
3006}

References GDS_my_identity.