aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs.h
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-01-20 14:20:30 +0000
committerChristian Grothoff <christian@grothoff.org>2011-01-20 14:20:30 +0000
commitc9432075d84d3c50171367e7d648a3a09f431994 (patch)
tree816f97d3601f6f255354267225c3b43b076fdac7 /src/fs/fs.h
parent81dfe20c8ee82d202244766f2914683a63d078ca (diff)
downloadgnunet-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.h216
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.
1615o */ 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 */
1653enum 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 */
1650struct DownloadRequest 1722struct 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 */
1688struct ReconstructContext; 1785void
1786GNUNET_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