diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-01-20 14:20:30 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-01-20 14:20:30 +0000 |
commit | c9432075d84d3c50171367e7d648a3a09f431994 (patch) | |
tree | 816f97d3601f6f255354267225c3b43b076fdac7 /src/fs/fs.h | |
parent | 81dfe20c8ee82d202244766f2914683a63d078ca (diff) | |
download | gnunet-c9432075d84d3c50171367e7d648a3a09f431994.tar.gz gnunet-c9432075d84d3c50171367e7d648a3a09f431994.zip |
major rewrite of fs_download, hopefully fixing 1641
Diffstat (limited to 'src/fs/fs.h')
-rw-r--r-- | src/fs/fs.h | 216 |
1 files changed, 156 insertions, 60 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h index 0ba1d08a1..a9aa7ef74 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -925,6 +925,7 @@ GNUNET_FS_download_start_task_ (void *cls, | |||
925 | const struct GNUNET_SCHEDULER_TaskContext *tc); | 925 | const struct GNUNET_SCHEDULER_TaskContext *tc); |
926 | 926 | ||
927 | 927 | ||
928 | |||
928 | /** | 929 | /** |
929 | * Fill in all of the generic fields for | 930 | * Fill in all of the generic fields for |
930 | * an unindex event and call the callback. | 931 | * an unindex event and call the callback. |
@@ -1612,7 +1613,7 @@ struct GNUNET_FS_SearchContext | |||
1612 | * when the search is being stopped (if not | 1613 | * when the search is being stopped (if not |
1613 | * GNUNET_SCHEDULER_NO_TASK). Used for the task that adds some | 1614 | * GNUNET_SCHEDULER_NO_TASK). Used for the task that adds some |
1614 | * artificial delay when trying to reconnect to the FS service. | 1615 | * artificial delay when trying to reconnect to the FS service. |
1615 | o */ | 1616 | */ |
1616 | GNUNET_SCHEDULER_TaskIdentifier task; | 1617 | GNUNET_SCHEDULER_TaskIdentifier task; |
1617 | 1618 | ||
1618 | /** | 1619 | /** |
@@ -1645,37 +1646,131 @@ o */ | |||
1645 | 1646 | ||
1646 | 1647 | ||
1647 | /** | 1648 | /** |
1649 | * FSM for possible states a block can go through. The typical | ||
1650 | * order of progression is linear through the states, alternatives | ||
1651 | * are documented in the comments. | ||
1652 | */ | ||
1653 | enum BlockRequestState | ||
1654 | { | ||
1655 | /** | ||
1656 | * Initial state, block has only been allocated (since it is | ||
1657 | * relevant to the overall download request). | ||
1658 | */ | ||
1659 | BRS_INIT = 0, | ||
1660 | |||
1661 | /** | ||
1662 | * We've checked the block on the path down the tree, and the | ||
1663 | * content on disk did match the desired CHK, but not all | ||
1664 | * the way down, so at the bottom some blocks will still | ||
1665 | * need to be reconstructed). | ||
1666 | */ | ||
1667 | BRS_RECONSTRUCT_DOWN = 1, | ||
1668 | |||
1669 | /** | ||
1670 | * We've calculated the CHK bottom-up based on the meta data. | ||
1671 | * This may work, but if it did we have to write the meta data to | ||
1672 | * disk at the end (and we still need to check against the | ||
1673 | * CHK set on top). | ||
1674 | */ | ||
1675 | BRS_RECONSTRUCT_META_UP = 2, | ||
1676 | |||
1677 | /** | ||
1678 | * We've calculated the CHK bottom-up based on what we have on | ||
1679 | * disk, which may not be what the desired CHK is. If the | ||
1680 | * reconstructed CHKs match whatever comes from above, we're | ||
1681 | * done with the respective subtree. | ||
1682 | */ | ||
1683 | BRS_RECONSTRUCT_UP = 3, | ||
1684 | |||
1685 | /** | ||
1686 | * We've determined the real, desired CHK for this block | ||
1687 | * (full tree reconstruction failed), request is now pending. | ||
1688 | * If the CHK that bubbled up through reconstruction did match | ||
1689 | * the top-level request, the state machine for the subtree | ||
1690 | * would have moved to BRS_DOWNLOAD_UP. | ||
1691 | */ | ||
1692 | BRS_CHK_SET = 4, | ||
1693 | |||
1694 | /** | ||
1695 | * We've successfully downloaded this block, but the children | ||
1696 | * still need to be either downloaded or verified (download | ||
1697 | * request propagates down). If the download fails, the | ||
1698 | * state machine for this block may move to | ||
1699 | * BRS_DOWNLOAD_ERROR instead. | ||
1700 | */ | ||
1701 | BRS_DOWNLOAD_DOWN = 5, | ||
1702 | |||
1703 | /** | ||
1704 | * This block and all of its children have been downloaded | ||
1705 | * successfully (full completion propagates up). | ||
1706 | */ | ||
1707 | BRS_DOWNLOAD_UP = 6, | ||
1708 | |||
1709 | /** | ||
1710 | * We got a block back that matched the query but did not hash to | ||
1711 | * the key (malicious publisher or hash collision); this block | ||
1712 | * can never be downloaded (error propagates up). | ||
1713 | */ | ||
1714 | BRS_ERROR = 7 | ||
1715 | |||
1716 | }; | ||
1717 | |||
1718 | |||
1719 | /** | ||
1648 | * Information about an active download request. | 1720 | * Information about an active download request. |
1649 | */ | 1721 | */ |
1650 | struct DownloadRequest | 1722 | struct DownloadRequest |
1651 | { | 1723 | { |
1652 | /** | 1724 | /** |
1653 | * While pending, we keep all download requests in a linked list. | 1725 | * While pending, we keep all download requests in a doubly-linked list. |
1654 | */ | 1726 | */ |
1655 | struct DownloadRequest *next; | 1727 | struct DownloadRequest *next; |
1656 | 1728 | ||
1657 | /** | 1729 | /** |
1658 | * CHK for the request. | 1730 | * While pending, we keep all download requests in a doubly-linked list. |
1659 | */ | 1731 | */ |
1660 | struct ContentHashKey chk; | 1732 | struct DownloadRequest *prev; |
1733 | |||
1734 | /** | ||
1735 | * Parent in the CHK-tree. | ||
1736 | */ | ||
1737 | struct DownloadRequest *parent; | ||
1738 | |||
1739 | /** | ||
1740 | * Array (!) of child-requests, or NULL for the bottom of the tree. | ||
1741 | */ | ||
1742 | struct DownloadRequest **children; | ||
1661 | 1743 | ||
1662 | /** | 1744 | /** |
1663 | * Offset of the corresponding block. | 1745 | * CHK for the request for this block (set during reconstruction |
1746 | * to what we have on disk, later to what we want to have). | ||
1747 | */ | ||
1748 | struct ContentHashKey chk; | ||
1749 | |||
1750 | /** | ||
1751 | * Offset of the corresponding block. Specifically, first (!) byte of | ||
1752 | * the first DBLOCK in the subtree induced by block represented by | ||
1753 | * this request. | ||
1664 | */ | 1754 | */ |
1665 | uint64_t offset; | 1755 | uint64_t offset; |
1666 | 1756 | ||
1667 | /** | 1757 | /** |
1668 | * Depth of the corresponding block in the tree. | 1758 | * Number of entries in 'children' array. |
1759 | */ | ||
1760 | unsigned int num_children; | ||
1761 | |||
1762 | /** | ||
1763 | * Depth of the corresponding block in the tree. 0==DBLOCKs. | ||
1669 | */ | 1764 | */ |
1670 | unsigned int depth; | 1765 | unsigned int depth; |
1671 | 1766 | ||
1672 | /** | 1767 | /** |
1673 | * Set if this request is currently in the linked list of pending | 1768 | * State in the FSM. |
1674 | * requests. Needed in case we get a response for a request that we | 1769 | */ |
1675 | * have not yet send (i.e. due to two blocks with identical | 1770 | enum BlockRequestState state; |
1676 | * content); in this case, we would need to remove the block from | 1771 | |
1677 | * the pending list (and need a fast way to check if the block is on | 1772 | /** |
1678 | * it). | 1773 | * GNUNET_YES if this entry is in the pending list. |
1679 | */ | 1774 | */ |
1680 | int is_pending; | 1775 | int is_pending; |
1681 | 1776 | ||
@@ -1683,9 +1778,12 @@ struct DownloadRequest | |||
1683 | 1778 | ||
1684 | 1779 | ||
1685 | /** | 1780 | /** |
1686 | * Closure for 'reconstruct_cont' and 'reconstruct_cb'. | 1781 | * (recursively) free download request structure |
1782 | * | ||
1783 | * @param dr request to free | ||
1687 | */ | 1784 | */ |
1688 | struct ReconstructContext; | 1785 | void |
1786 | GNUNET_FS_free_download_request_ (struct DownloadRequest *dr); | ||
1689 | 1787 | ||
1690 | 1788 | ||
1691 | /** | 1789 | /** |
@@ -1732,11 +1830,6 @@ struct GNUNET_FS_DownloadContext | |||
1732 | struct GNUNET_FS_DownloadContext *child_tail; | 1830 | struct GNUNET_FS_DownloadContext *child_tail; |
1733 | 1831 | ||
1734 | /** | 1832 | /** |
1735 | * State for block reconstruction. | ||
1736 | */ | ||
1737 | struct ReconstructContext *rcc; | ||
1738 | |||
1739 | /** | ||
1740 | * Previous download belonging to the same parent. | 1833 | * Previous download belonging to the same parent. |
1741 | */ | 1834 | */ |
1742 | struct GNUNET_FS_DownloadContext *prev; | 1835 | struct GNUNET_FS_DownloadContext *prev; |
@@ -1752,8 +1845,7 @@ struct GNUNET_FS_DownloadContext | |||
1752 | void *client_info; | 1845 | void *client_info; |
1753 | 1846 | ||
1754 | /** | 1847 | /** |
1755 | * URI that identifies the file that | 1848 | * URI that identifies the file that we are downloading. |
1756 | * we are downloading. | ||
1757 | */ | 1849 | */ |
1758 | struct GNUNET_FS_Uri *uri; | 1850 | struct GNUNET_FS_Uri *uri; |
1759 | 1851 | ||
@@ -1787,16 +1879,9 @@ struct GNUNET_FS_DownloadContext | |||
1787 | char *temp_filename; | 1879 | char *temp_filename; |
1788 | 1880 | ||
1789 | /** | 1881 | /** |
1790 | * Map of active requests (those waiting | 1882 | * Our entry in the job queue. |
1791 | * for a response). The key is the hash | ||
1792 | * of the encryped block (aka query). | ||
1793 | */ | ||
1794 | struct GNUNET_CONTAINER_MultiHashMap *active; | ||
1795 | |||
1796 | /** | ||
1797 | * Linked list of pending requests. | ||
1798 | */ | 1883 | */ |
1799 | struct DownloadRequest *pending; | 1884 | struct GNUNET_FS_QueueEntry *job_queue; |
1800 | 1885 | ||
1801 | /** | 1886 | /** |
1802 | * Non-NULL if we are currently having a request for | 1887 | * Non-NULL if we are currently having a request for |
@@ -1805,38 +1890,52 @@ struct GNUNET_FS_DownloadContext | |||
1805 | struct GNUNET_CLIENT_TransmitHandle *th; | 1890 | struct GNUNET_CLIENT_TransmitHandle *th; |
1806 | 1891 | ||
1807 | /** | 1892 | /** |
1808 | * Our entry in the job queue. | 1893 | * Tree encoder used for the reconstruction. |
1809 | */ | 1894 | */ |
1810 | struct GNUNET_FS_QueueEntry *job_queue; | 1895 | struct GNUNET_FS_TreeEncoder *te; |
1811 | 1896 | ||
1812 | /** | 1897 | /** |
1813 | * Identity of the peer having the content, or all-zeros | 1898 | * File handle for reading data from an existing file |
1814 | * if we don't know of such a peer. | 1899 | * (to pass to tree encoder). |
1815 | */ | 1900 | */ |
1816 | struct GNUNET_PeerIdentity target; | 1901 | struct GNUNET_DISK_FileHandle *rfh; |
1817 | 1902 | ||
1818 | /** | 1903 | /** |
1819 | * ID of a task that is using this struct | 1904 | * Map of active requests (those waiting for a response). The key |
1820 | * and that must be cancelled when the download | 1905 | * is the hash of the encryped block (aka query). |
1821 | * is being stopped (if not GNUNET_SCHEDULER_NO_TASK). | ||
1822 | * Used for the task that adds some artificial | ||
1823 | * delay when trying to reconnect to the FS | ||
1824 | * service. | ||
1825 | */ | 1906 | */ |
1826 | GNUNET_SCHEDULER_TaskIdentifier task; | 1907 | struct GNUNET_CONTAINER_MultiHashMap *active; |
1827 | 1908 | ||
1828 | /** | 1909 | /** |
1829 | * Task used to start the download. | 1910 | * Head of linked list of pending requests. |
1830 | */ | 1911 | */ |
1831 | GNUNET_SCHEDULER_TaskIdentifier start_task; | 1912 | struct DownloadRequest *pending_head; |
1832 | 1913 | ||
1833 | /** | 1914 | /** |
1834 | * What was the size of the file on disk that we're downloading | 1915 | * Head of linked list of pending requests. |
1835 | * before we started? Used to detect if there is a point in | ||
1836 | * checking an existing block on disk for matching the desired | ||
1837 | * content. 0 if the file did not exist already. | ||
1838 | */ | 1916 | */ |
1839 | uint64_t old_file_size; | 1917 | struct DownloadRequest *pending_tail; |
1918 | |||
1919 | /** | ||
1920 | * Top-level download request. | ||
1921 | */ | ||
1922 | struct DownloadRequest *top_request; | ||
1923 | |||
1924 | /** | ||
1925 | * Identity of the peer having the content, or all-zeros | ||
1926 | * if we don't know of such a peer. | ||
1927 | */ | ||
1928 | struct GNUNET_PeerIdentity target; | ||
1929 | |||
1930 | /** | ||
1931 | * ID of a task that is using this struct and that must be cancelled | ||
1932 | * when the download is being stopped (if not | ||
1933 | * GNUNET_SCHEDULER_NO_TASK). Used for the task that adds some | ||
1934 | * artificial delay when trying to reconnect to the FS service or | ||
1935 | * the task processing incrementally the data on disk, or the | ||
1936 | * task requesting blocks, etc. | ||
1937 | */ | ||
1938 | GNUNET_SCHEDULER_TaskIdentifier task; | ||
1840 | 1939 | ||
1841 | /** | 1940 | /** |
1842 | * What is the first offset that we're interested | 1941 | * What is the first offset that we're interested |
@@ -1857,6 +1956,14 @@ struct GNUNET_FS_DownloadContext | |||
1857 | uint64_t completed; | 1956 | uint64_t completed; |
1858 | 1957 | ||
1859 | /** | 1958 | /** |
1959 | * What was the size of the file on disk that we're downloading | ||
1960 | * before we started? Used to detect if there is a point in | ||
1961 | * checking an existing block on disk for matching the desired | ||
1962 | * content. 0 if the file did not exist already. | ||
1963 | */ | ||
1964 | uint64_t old_file_size; | ||
1965 | |||
1966 | /** | ||
1860 | * Time download was started. | 1967 | * Time download was started. |
1861 | */ | 1968 | */ |
1862 | struct GNUNET_TIME_Absolute start_time; | 1969 | struct GNUNET_TIME_Absolute start_time; |
@@ -1883,17 +1990,6 @@ struct GNUNET_FS_DownloadContext | |||
1883 | */ | 1990 | */ |
1884 | int has_finished; | 1991 | int has_finished; |
1885 | 1992 | ||
1886 | /** | ||
1887 | * Have we tried (and failed) to find matching full | ||
1888 | * data from the meta data yet? | ||
1889 | */ | ||
1890 | int tried_full_data; | ||
1891 | |||
1892 | /** | ||
1893 | * Have we tried to reconstruct an IBLOCK from disk | ||
1894 | * and failed (and should hence not try again?) | ||
1895 | */ | ||
1896 | int reconstruct_failed; | ||
1897 | }; | 1993 | }; |
1898 | 1994 | ||
1899 | 1995 | ||