aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c200
1 files changed, 169 insertions, 31 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index f9e31310e..705168b17 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -28,6 +28,7 @@
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_block_lib.h" 29#include "gnunet_block_lib.h"
30#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
31#include "gnunet_hello_lib.h"
31#include "gnunet_constants.h" 32#include "gnunet_constants.h"
32#include "gnunet_protocols.h" 33#include "gnunet_protocols.h"
33#include "gnunet_nse_service.h" 34#include "gnunet_nse_service.h"
@@ -37,6 +38,7 @@
37#include "gnunet_hello_lib.h" 38#include "gnunet_hello_lib.h"
38#include "gnunet_dht_service.h" 39#include "gnunet_dht_service.h"
39#include "gnunet_statistics_service.h" 40#include "gnunet_statistics_service.h"
41#include "gnunet_peerinfo_service.h"
40#include "dht.h" 42#include "dht.h"
41#include "gnunet-service-dht.h" 43#include "gnunet-service-dht.h"
42#include "gnunet-service-dht_clients.h" 44#include "gnunet-service-dht_clients.h"
@@ -326,9 +328,10 @@ struct PeerInfo
326 struct GNUNET_CORE_InformationRequestContext *info_ctx; 328 struct GNUNET_CORE_InformationRequestContext *info_ctx;
327 329
328 /** 330 /**
329 * Task for scheduling message sends. 331 * HELLO message for the peer, NULL if not known. FIXME: track
332 * separately? FIXME: free!?
330 */ 333 */
331 GNUNET_SCHEDULER_TaskIdentifier send_task; 334 struct GNUNET_HELLO_Message *hello;
332 335
333 /** 336 /**
334 * Task for scheduling preference updates 337 * Task for scheduling preference updates
@@ -418,6 +421,11 @@ static struct GNUNET_PeerIdentity my_identity;
418 */ 421 */
419static struct GNUNET_CORE_Handle *coreAPI; 422static struct GNUNET_CORE_Handle *coreAPI;
420 423
424/**
425 * Handle for peerinfo notifications.
426 */
427static struct GNUNET_PEERINFO_NotifyContext *pnc;
428
421 429
422/** 430/**
423 * Find the optimal bucket for this key. 431 * Find the optimal bucket for this key.
@@ -1511,6 +1519,81 @@ handle_dht_p2p_put (void *cls,
1511 1519
1512 1520
1513/** 1521/**
1522 * We have received a FIND PEER request. Send matching
1523 * HELLOs back.
1524 *
1525 * @param sender sender of the FIND PEER request
1526 * @param key peers close to this key are desired
1527 * @param bf peers matching this bf are excluded
1528 * @param bf_mutator mutator for bf
1529 */
1530static void
1531handle_find_peer (const struct GNUNET_PeerIdentity *sender,
1532 const GNUNET_HashCode *key,
1533 struct GNUNET_CONTAINER_BloomFilter *bf,
1534 uint32_t bf_mutator)
1535{
1536 int bucket_idx;
1537 struct PeerBucket *bucket;
1538 struct PeerInfo *peer;
1539 unsigned int choice;
1540 GNUNET_HashCode mhash;
1541
1542 /* first, check about our own HELLO */
1543 if (NULL != GDS_my_hello)
1544 {
1545 GNUNET_BLOCK_mingle_hash (&my_identity.hashPubKey, bf_mutator, &mhash);
1546 if (GNUNET_YES != GNUNET_CONTAINER_bloomfilter_test (bf, &mhash))
1547
1548 GDS_NEIGHBOURS_handle_reply (sender,
1549 GNUNET_BLOCK_TYPE_DHT_HELLO,
1550 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION),
1551 key,
1552 0, NULL,
1553 0, NULL,
1554 GDS_my_hello,
1555 GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message*) GDS_my_hello));
1556 }
1557
1558 /* then, also consider sending a random HELLO from the closest bucket */
1559 bucket_idx = find_bucket (key);
1560 if (bucket_idx == GNUNET_SYSERR)
1561 return;
1562 bucket = &k_buckets[bucket_idx];
1563 if (bucket->peers_size == 0)
1564 return;
1565 choice = GNUNET_CRYPTO_random_u32 (bucket->peers_size,
1566 GNUNET_CRYPTO_QUALITY_WEAK);
1567 peer = bucket->head;
1568 while (choice > 0)
1569 {
1570 GNUNET_assert (peer != NULL);
1571 peer = peer->next;
1572 }
1573 choice = bucket->peers_size;
1574 do
1575 {
1576 peer = peer->next;
1577 if (choice-- == 0)
1578 return; /* no non-masked peer available */
1579 if (peer == NULL)
1580 peer = bucket->head;
1581 GNUNET_BLOCK_mingle_hash (&peer->id.hashPubKey, bf_mutator, &mhash);
1582 }
1583 while ( (peer->hello == NULL) ||
1584 (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (bf, &mhash)) );
1585 GDS_NEIGHBOURS_handle_reply (sender,
1586 GNUNET_BLOCK_TYPE_DHT_HELLO,
1587 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION),
1588 key,
1589 0, NULL,
1590 0, NULL,
1591 peer->hello,
1592 GNUNET_HELLO_size (peer->hello));
1593}
1594
1595
1596/**
1514 * Core handler for p2p get requests. 1597 * Core handler for p2p get requests.
1515 * 1598 *
1516 * @param cls closure 1599 * @param cls closure
@@ -1588,19 +1671,30 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1588 &get->key, 1671 &get->key,
1589 xquery, xquery_size, 1672 xquery, xquery_size,
1590 reply_bf, get->bf_mutator); 1673 reply_bf, get->bf_mutator);
1591 /* FIXME: check options (find peer, local-processing-only-if-nearest, etc.!) */
1592 1674
1593 /* local lookup (this may update the reply_bf) */ 1675 /* local lookup (this may update the reply_bf) */
1594 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 1676 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
1595 (am_closest_peer (&get->key, 1677 (am_closest_peer (&get->key,
1596 peer_bf) ) ) 1678 peer_bf) ) )
1597 GDS_DATACACHE_handle_get (&get->key, 1679 {
1598 type, 1680 if ( (0 != (options & GNUNET_DHT_RO_FIND_PEER)))
1599 xquery, xquery_size, 1681 {
1600 &reply_bf, 1682 handle_find_peer (peer,
1601 get->bf_mutator); 1683 &get->key,
1602 /* FIXME: should track if the local lookup resulted in a 1684 reply_bf,
1603 definitive result and then NOT do P2P forwarding */ 1685 get->bf_mutator);
1686 }
1687 else
1688 {
1689 GDS_DATACACHE_handle_get (&get->key,
1690 type,
1691 xquery, xquery_size,
1692 &reply_bf,
1693 get->bf_mutator);
1694 /* FIXME: should track if the local lookup resulted in a
1695 definitive result and then NOT do P2P forwarding */
1696 }
1697 }
1604 1698
1605 /* P2P forwarding */ 1699 /* P2P forwarding */
1606 GDS_NEIGHBOURS_handle_get (type, 1700 GDS_NEIGHBOURS_handle_get (type,
@@ -1669,6 +1763,44 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer,
1669 data = (const void*) &get_path[get_path_length]; 1763 data = (const void*) &get_path[get_path_length];
1670 data_size = msize - (sizeof (struct PeerResultMessage) + 1764 data_size = msize - (sizeof (struct PeerResultMessage) +
1671 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity)); 1765 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity));
1766 if (type == GNUNET_BLOCK_TYPE_DHT_HELLO)
1767 {
1768 const struct GNUNET_MessageHeader *h;
1769 struct GNUNET_PeerIdentity pid;
1770 int bucket;
1771
1772 /* Should be a HELLO, validate and consider using it! */
1773 if (data_size < sizeof (struct GNUNET_MessageHeader))
1774 {
1775 GNUNET_break_op (0);
1776 return GNUNET_YES;
1777 }
1778 h = data;
1779 if (data_size != ntohs (h->size))
1780 {
1781 GNUNET_break_op (0);
1782 return GNUNET_YES;
1783 }
1784 if (GNUNET_OK !=
1785 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message*) h,
1786 &pid))
1787 {
1788 GNUNET_break_op (0);
1789 return GNUNET_YES;
1790 }
1791 bucket = find_bucket (&pid.hashPubKey);
1792 if ( (bucket >= 0) &&
1793 (k_buckets[bucket].peers_size < bucket_size) )
1794 {
1795 if (NULL != GDS_transport_handle)
1796 GNUNET_TRANSPORT_offer_hello (GDS_transport_handle,
1797 h, NULL, NULL);
1798 (void) GNUNET_CORE_peer_request_connect (coreAPI,
1799 &pid,
1800 NULL, NULL);
1801 }
1802 }
1803
1672 /* append 'peer' to 'get_path' */ 1804 /* append 'peer' to 'get_path' */
1673 { 1805 {
1674 struct GNUNET_PeerIdentity xget_path[get_path_length+1]; 1806 struct GNUNET_PeerIdentity xget_path[get_path_length+1];
@@ -1704,6 +1836,25 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer,
1704 1836
1705 1837
1706/** 1838/**
1839 * Function called for each HELLO known to PEERINFO.
1840 *
1841 * @param cls closure
1842 * @param peer id of the peer, NULL for last call
1843 * @param hello hello message for the peer (can be NULL)
1844 * @param error message
1845 */
1846static void
1847process_hello (void *cls,
1848 const struct GNUNET_PeerIdentity *
1849 peer,
1850 const struct GNUNET_HELLO_Message *
1851 hello, const char *err_msg)
1852{
1853 // FIXME: track HELLOs, possibly ask core to establish connections
1854}
1855
1856
1857/**
1707 * Initialize neighbours subsystem. 1858 * Initialize neighbours subsystem.
1708 * 1859 *
1709 * @return GNUNET_OK on success, GNUNET_SYSERR on error 1860 * @return GNUNET_OK on success, GNUNET_SYSERR on error
@@ -1736,20 +1887,9 @@ GDS_NEIGHBOURS_init ()
1736 if (coreAPI == NULL) 1887 if (coreAPI == NULL)
1737 return GNUNET_SYSERR; 1888 return GNUNET_SYSERR;
1738 all_known_peers = GNUNET_CONTAINER_multihashmap_create (256); 1889 all_known_peers = GNUNET_CONTAINER_multihashmap_create (256);
1739#if 0 1890 pnc = GNUNET_PEERINFO_notify (GDS_cfg,
1740 struct GNUNET_TIME_Relative next_send_time; 1891 &process_hello,
1741 1892 NULL);
1742 // FIXME!
1743 next_send_time.rel_value =
1744 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value +
1745 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1746 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value /
1747 2) -
1748 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value);
1749 find_peer_task = GNUNET_SCHEDULER_add_delayed (next_send_time,
1750 &send_find_peer_message,
1751 &find_peer_context);
1752#endif
1753 return GNUNET_OK; 1893 return GNUNET_OK;
1754} 1894}
1755 1895
@@ -1762,6 +1902,11 @@ GDS_NEIGHBOURS_done ()
1762{ 1902{
1763 if (coreAPI == NULL) 1903 if (coreAPI == NULL)
1764 return; 1904 return;
1905 if (NULL != pnc)
1906 {
1907 GNUNET_PEERINFO_notify_cancel (pnc);
1908 pnc = NULL;
1909 }
1765 GNUNET_CORE_disconnect (coreAPI); 1910 GNUNET_CORE_disconnect (coreAPI);
1766 coreAPI = NULL; 1911 coreAPI = NULL;
1767 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (all_known_peers)); 1912 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (all_known_peers));
@@ -1776,10 +1921,3 @@ GDS_NEIGHBOURS_done ()
1776 1921
1777 1922
1778/* end of gnunet-service-dht_neighbours.c */ 1923/* end of gnunet-service-dht_neighbours.c */
1779
1780
1781#if 0
1782
1783
1784
1785#endif