X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ffs%2Ffs_tree.c;h=5d486a8c94d3cbe7e3604947b6a14c6ba9d152a4;hb=d41ed82a4ea0cc8e1674b6d5d2c49fd6462610bb;hp=715ecddb15f028753edcb14019ec9e06df5c76a3;hpb=f1f603c7d0b3f03dca46a4f313472288eb080eb1;p=oweals%2Fgnunet.git diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c index 715ecddb1..5d486a8c9 100644 --- a/src/fs/fs_tree.c +++ b/src/fs/fs_tree.c @@ -1,22 +1,22 @@ /* This file is part of GNUnet. - (C) 2009-2011 Christian Grothoff (and other contributing authors) + Copyright (C) 2009-2011 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Affero General Public License for more details. - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ /** * @file fs/fs_tree.c * @brief Merkle-tree-ish-CHK file encoding for GNUnet @@ -32,9 +32,7 @@ * Context for an ECRS-based file encoder that computes * the Merkle-ish-CHK tree. */ -struct GNUNET_FS_TreeEncoder -{ - +struct GNUNET_FS_TreeEncoder { /** * Global FS context. */ @@ -123,7 +121,7 @@ struct GNUNET_FS_TreeEncoder * @return depth of the tree, always > 0. A depth of 1 means only a DBLOCK. */ unsigned int -GNUNET_FS_compute_depth (uint64_t flen) +GNUNET_FS_compute_depth(uint64_t flen) { unsigned int treeDepth; uint64_t fl; @@ -131,15 +129,15 @@ GNUNET_FS_compute_depth (uint64_t flen) treeDepth = 1; fl = DBLOCK_SIZE; while (fl < flen) - { - treeDepth++; - if (fl * CHK_PER_INODE < fl) { - /* integer overflow, this is a HUGE file... */ - return treeDepth; + treeDepth++; + if (fl * CHK_PER_INODE < fl) + { + /* integer overflow, this is a HUGE file... */ + return treeDepth; + } + fl = fl * CHK_PER_INODE; } - fl = fl * CHK_PER_INODE; - } return treeDepth; } @@ -154,7 +152,7 @@ GNUNET_FS_compute_depth (uint64_t flen) * @return number of bytes of payload a subtree of this depth may correspond to */ uint64_t -GNUNET_FS_tree_compute_tree_size (unsigned int depth) +GNUNET_FS_tree_compute_tree_size(unsigned int depth) { uint64_t rsize; unsigned int i; @@ -181,30 +179,30 @@ GNUNET_FS_tree_compute_tree_size (unsigned int depth) * @return size of the corresponding IBlock */ static uint16_t -GNUNET_FS_tree_compute_iblock_size (unsigned int depth, uint64_t end_offset) +GNUNET_FS_tree_compute_iblock_size(unsigned int depth, uint64_t end_offset) { unsigned int ret; uint64_t mod; uint64_t bds; - GNUNET_assert (depth > 0); - GNUNET_assert (end_offset > 0); - bds = GNUNET_FS_tree_compute_tree_size (depth); + GNUNET_assert(depth > 0); + GNUNET_assert(end_offset > 0); + bds = GNUNET_FS_tree_compute_tree_size(depth); mod = end_offset % bds; if (0 == mod) - { - /* we were triggered at the end of a full block */ - ret = CHK_PER_INODE; - } + { + /* we were triggered at the end of a full block */ + ret = CHK_PER_INODE; + } else - { - /* we were triggered at the end of the file */ - bds /= CHK_PER_INODE; - ret = mod / bds; - if (0 != mod % bds) - ret++; - } - return (uint16_t) (ret * sizeof (struct ContentHashKey)); + { + /* we were triggered at the end of the file */ + bds /= CHK_PER_INODE; + ret = mod / bds; + if (0 != mod % bds) + ret++; + } + return (uint16_t)(ret * sizeof(struct ContentHashKey)); } @@ -220,32 +218,32 @@ GNUNET_FS_tree_compute_iblock_size (unsigned int depth, uint64_t end_offset) * @return number of bytes stored in this node */ size_t -GNUNET_FS_tree_calculate_block_size (uint64_t fsize, uint64_t offset, - unsigned int depth) +GNUNET_FS_tree_calculate_block_size(uint64_t fsize, uint64_t offset, + unsigned int depth) { size_t ret; uint64_t rsize; uint64_t epos; unsigned int chks; - GNUNET_assert (fsize > 0); - GNUNET_assert (offset <= fsize); + GNUNET_assert(fsize > 0); + GNUNET_assert(offset <= fsize); if (depth == 0) - { - ret = DBLOCK_SIZE; - if ((offset + ret > fsize) || (offset + ret < offset)) - ret = (size_t) (fsize - offset); - return ret; - } - - rsize = GNUNET_FS_tree_compute_tree_size (depth - 1); + { + ret = DBLOCK_SIZE; + if ((offset + ret > fsize) || (offset + ret < offset)) + ret = (size_t)(fsize - offset); + return ret; + } + + rsize = GNUNET_FS_tree_compute_tree_size(depth - 1); epos = offset + rsize * CHK_PER_INODE; if ((epos < offset) || (epos > fsize)) epos = fsize; /* round up when computing #CHKs in our IBlock */ chks = (epos - offset + rsize - 1) / rsize; - GNUNET_assert (chks <= CHK_PER_INODE); - return chks * sizeof (struct ContentHashKey); + GNUNET_assert(chks <= CHK_PER_INODE); + return chks * sizeof(struct ContentHashKey); } @@ -267,16 +265,16 @@ GNUNET_FS_tree_calculate_block_size (uint64_t fsize, uint64_t offset, * @param cont function to call when done */ struct GNUNET_FS_TreeEncoder * -GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, uint64_t size, - void *cls, - GNUNET_FS_DataReader reader, - GNUNET_FS_TreeBlockProcessor proc, - GNUNET_FS_TreeProgressCallback progress, - GNUNET_SCHEDULER_TaskCallback cont) +GNUNET_FS_tree_encoder_create(struct GNUNET_FS_Handle *h, uint64_t size, + void *cls, + GNUNET_FS_DataReader reader, + GNUNET_FS_TreeBlockProcessor proc, + GNUNET_FS_TreeProgressCallback progress, + GNUNET_SCHEDULER_TaskCallback cont) { struct GNUNET_FS_TreeEncoder *te; - te = GNUNET_new (struct GNUNET_FS_TreeEncoder); + te = GNUNET_new(struct GNUNET_FS_TreeEncoder); te->h = h; te->size = size; te->cls = cls; @@ -284,14 +282,14 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, uint64_t size, te->proc = proc; te->progress = progress; te->cont = cont; - te->chk_tree_depth = GNUNET_FS_compute_depth (size); - te->chk_tree = - GNUNET_malloc (te->chk_tree_depth * CHK_PER_INODE * - sizeof (struct ContentHashKey)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created tree encoder for file with %llu bytes and depth %u\n", - (unsigned long long) size, - te->chk_tree_depth); + te->chk_tree_depth = GNUNET_FS_compute_depth(size); + te->chk_tree + = GNUNET_new_array(te->chk_tree_depth * CHK_PER_INODE, + struct ContentHashKey); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Created tree encoder for file with %llu bytes and depth %u\n", + (unsigned long long)size, + te->chk_tree_depth); return te; } @@ -308,12 +306,12 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, uint64_t size, * @return (array of CHKs') offset in the above IBlock */ static unsigned int -compute_chk_offset (unsigned int depth, uint64_t end_offset) +compute_chk_offset(unsigned int depth, uint64_t end_offset) { uint64_t bds; unsigned int ret; - bds = GNUNET_FS_tree_compute_tree_size (depth); + bds = GNUNET_FS_tree_compute_tree_size(depth); if (depth > 0) end_offset--; /* round down since for depth > 0 offset is at the END of the block */ ret = end_offset / bds; @@ -329,7 +327,7 @@ compute_chk_offset (unsigned int depth, uint64_t end_offset) * @param te tree encoder to use */ void -GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te) +GNUNET_FS_tree_encoder_next(struct GNUNET_FS_TreeEncoder *te) { struct ContentHashKey *mychk; const void *pt_block; @@ -340,77 +338,77 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te) struct GNUNET_CRYPTO_SymmetricInitializationVector iv; unsigned int off; - GNUNET_assert (GNUNET_NO == te->in_next); + GNUNET_assert(GNUNET_NO == te->in_next); te->in_next = GNUNET_YES; if (te->chk_tree_depth == te->current_depth) - { - off = CHK_PER_INODE * (te->chk_tree_depth - 1); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TE done, reading CHK `%s' from %u\n", - GNUNET_h2s (&te->chk_tree[off].query), off); - te->uri = GNUNET_new (struct GNUNET_FS_Uri); - te->uri->type = GNUNET_FS_URI_CHK; - te->uri->data.chk.chk = te->chk_tree[off]; - te->uri->data.chk.file_length = GNUNET_htonll (te->size); - te->in_next = GNUNET_NO; - te->cont (te->cls, NULL); - return; - } - if (0 == te->current_depth) - { - /* read DBLOCK */ - pt_size = GNUNET_MIN (DBLOCK_SIZE, te->size - te->publish_offset); - if (pt_size != - te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg)) { + off = CHK_PER_INODE * (te->chk_tree_depth - 1); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "TE done, reading CHK `%s' from %u\n", + GNUNET_h2s(&te->chk_tree[off].query), off); + te->uri = GNUNET_new(struct GNUNET_FS_Uri); + te->uri->type = GNUNET_FS_URI_CHK; + te->uri->data.chk.chk = te->chk_tree[off]; + te->uri->data.chk.file_length = GNUNET_htonll(te->size); te->in_next = GNUNET_NO; - te->cont (te->cls, NULL); + te->cont(te->cls); return; } - pt_block = iob; - } + if (0 == te->current_depth) + { + /* read DBLOCK */ + pt_size = GNUNET_MIN(DBLOCK_SIZE, te->size - te->publish_offset); + if (pt_size != + te->reader(te->cls, te->publish_offset, pt_size, iob, &te->emsg)) + { + te->in_next = GNUNET_NO; + te->cont(te->cls); + return; + } + pt_block = iob; + } else - { - pt_size = - GNUNET_FS_tree_compute_iblock_size (te->current_depth, - te->publish_offset); - pt_block = &te->chk_tree[(te->current_depth - 1) * CHK_PER_INODE]; - } - off = compute_chk_offset (te->current_depth, te->publish_offset); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "TE is at offset %llu and depth %u with block size %u and target-CHK-offset %u\n", - (unsigned long long) te->publish_offset, te->current_depth, - (unsigned int) pt_size, (unsigned int) off); + { + pt_size = + GNUNET_FS_tree_compute_iblock_size(te->current_depth, + te->publish_offset); + pt_block = &te->chk_tree[(te->current_depth - 1) * CHK_PER_INODE]; + } + off = compute_chk_offset(te->current_depth, te->publish_offset); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "TE is at offset %llu and depth %u with block size %u and target-CHK-offset %u\n", + (unsigned long long)te->publish_offset, te->current_depth, + (unsigned int)pt_size, (unsigned int)off); mychk = &te->chk_tree[te->current_depth * CHK_PER_INODE + off]; - GNUNET_CRYPTO_hash (pt_block, pt_size, &mychk->key); - GNUNET_CRYPTO_hash_to_aes_key (&mychk->key, &sk, &iv); - GNUNET_CRYPTO_symmetric_encrypt (pt_block, pt_size, &sk, &iv, enc); - GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "TE calculates query to be `%s', stored at %u\n", - GNUNET_h2s (&mychk->query), - te->current_depth * CHK_PER_INODE + off); + GNUNET_CRYPTO_hash(pt_block, pt_size, &mychk->key); + GNUNET_CRYPTO_hash_to_aes_key(&mychk->key, &sk, &iv); + GNUNET_CRYPTO_symmetric_encrypt(pt_block, pt_size, &sk, &iv, enc); + GNUNET_CRYPTO_hash(enc, pt_size, &mychk->query); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "TE calculates query to be `%s', stored at %u\n", + GNUNET_h2s(&mychk->query), + te->current_depth * CHK_PER_INODE + off); if (NULL != te->proc) - te->proc (te->cls, mychk, te->publish_offset, te->current_depth, - (0 == - te->current_depth) ? GNUNET_BLOCK_TYPE_FS_DBLOCK : - GNUNET_BLOCK_TYPE_FS_IBLOCK, enc, pt_size); + te->proc(te->cls, mychk, te->publish_offset, te->current_depth, + (0 == + te->current_depth) ? GNUNET_BLOCK_TYPE_FS_DBLOCK : + GNUNET_BLOCK_TYPE_FS_IBLOCK, enc, pt_size); if (NULL != te->progress) - te->progress (te->cls, te->publish_offset, pt_block, pt_size, - te->current_depth); + te->progress(te->cls, te->publish_offset, pt_block, pt_size, + te->current_depth); if (0 == te->current_depth) - { - te->publish_offset += pt_size; - if ((te->publish_offset == te->size) || - (0 == te->publish_offset % (CHK_PER_INODE * DBLOCK_SIZE))) - te->current_depth++; - } + { + te->publish_offset += pt_size; + if ((te->publish_offset == te->size) || + (0 == te->publish_offset % (CHK_PER_INODE * DBLOCK_SIZE))) + te->current_depth++; + } else - { - if ((off == CHK_PER_INODE) || (te->publish_offset == te->size)) - te->current_depth++; - else - te->current_depth = 0; - } + { + if ((off == CHK_PER_INODE) || (te->publish_offset == te->size)) + te->current_depth++; + else + te->current_depth = 0; + } te->in_next = GNUNET_NO; } @@ -422,10 +420,10 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te) * @return uri set to the resulting URI (if encoding finished), NULL otherwise */ struct GNUNET_FS_Uri * -GNUNET_FS_tree_encoder_get_uri (struct GNUNET_FS_TreeEncoder *te) +GNUNET_FS_tree_encoder_get_uri(struct GNUNET_FS_TreeEncoder *te) { if (NULL != te->uri) - return GNUNET_FS_uri_dup (te->uri); + return GNUNET_FS_uri_dup(te->uri); return NULL; } @@ -441,23 +439,23 @@ GNUNET_FS_tree_encoder_get_uri (struct GNUNET_FS_TreeEncoder *te) * both "*emsg" will be set to NULL). */ void -GNUNET_FS_tree_encoder_finish (struct GNUNET_FS_TreeEncoder *te, - char **emsg) +GNUNET_FS_tree_encoder_finish(struct GNUNET_FS_TreeEncoder *te, + char **emsg) { if (NULL != te->reader) - { - (void) te->reader (te->cls, UINT64_MAX, 0, 0, NULL); - te->reader = NULL; - } - GNUNET_assert (GNUNET_NO == te->in_next); + { + (void)te->reader(te->cls, UINT64_MAX, 0, 0, NULL); + te->reader = NULL; + } + GNUNET_assert(GNUNET_NO == te->in_next); if (NULL != te->uri) - GNUNET_FS_uri_destroy (te->uri); + GNUNET_FS_uri_destroy(te->uri); if (emsg != NULL) *emsg = te->emsg; else - GNUNET_free_non_null (te->emsg); - GNUNET_free (te->chk_tree); - GNUNET_free (te); + GNUNET_free_non_null(te->emsg); + GNUNET_free(te->chk_tree); + GNUNET_free(te); } /* end of fs_tree.c */