diff options
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 200 |
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 | */ |
419 | static struct GNUNET_CORE_Handle *coreAPI; | 422 | static struct GNUNET_CORE_Handle *coreAPI; |
420 | 423 | ||
424 | /** | ||
425 | * Handle for peerinfo notifications. | ||
426 | */ | ||
427 | static 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 | */ | ||
1530 | static void | ||
1531 | handle_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 | */ | ||
1846 | static void | ||
1847 | process_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 | ||