gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r12248 - in gnunet: . src/fs src/include src/util


From: gnunet
Subject: [GNUnet-SVN] r12248 - in gnunet: . src/fs src/include src/util
Date: Fri, 16 Jul 2010 21:11:35 +0200

Author: grothoff
Date: 2010-07-16 21:11:35 +0200 (Fri, 16 Jul 2010)
New Revision: 12248

Modified:
   gnunet/TODO
   gnunet/src/fs/fs.h
   gnunet/src/fs/fs_download.c
   gnunet/src/include/gnunet_crypto_lib.h
   gnunet/src/util/crypto_rsa.c
Log:
inline downloads

Modified: gnunet/TODO
===================================================================
--- gnunet/TODO 2010-07-16 15:31:37 UTC (rev 12247)
+++ gnunet/TODO 2010-07-16 19:11:35 UTC (rev 12248)
@@ -17,10 +17,6 @@
   - implement testcases
   - implement performance tests
 * FS: [CG]
-  - library:
-    + utilize in-line files in meta data always (including in search results or
-      when download is triggered manually and for probes); currently the data 
is
-      only used when users do a general 'recursive' download
   - service:
     + trust: do not charge when "idle" / load considerations (migration, 
routing)
     + artificial delays

Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h  2010-07-16 15:31:37 UTC (rev 12247)
+++ gnunet/src/fs/fs.h  2010-07-16 19:11:35 UTC (rev 12248)
@@ -1832,6 +1832,11 @@
    */
   int has_finished;
 
+  /**
+   * Have we tried (and failed) to find matching full
+   * data from the meta data yet?
+   */
+  int tried_full_data;
 };
 
 struct GNUNET_FS_Namespace

Modified: gnunet/src/fs/fs_download.c
===================================================================
--- gnunet/src/fs/fs_download.c 2010-07-16 15:31:37 UTC (rev 12247)
+++ gnunet/src/fs/fs_download.c 2010-07-16 19:11:35 UTC (rev 12248)
@@ -249,8 +249,173 @@
                             void *value);
 
 
+/**
+ * We've found a matching block without downloading it.
+ * Encrypt it and pass it to our "receive" function as
+ * if we had received it from the network.
+ * 
+ * @param dc download in question
+ * @param chk request this relates to
+ * @param sm request details
+ * @param block plaintext data matching request
+ * @param len number of bytes in block
+ * @param depth depth of the block
+ * @param do_store should we still store the block on disk?
+ * @return GNUNET_OK on success
+ */
+static int
+encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc,
+                       const struct ContentHashKey *chk,
+                       struct DownloadRequest *sm,
+                       const char * block,                    
+                       size_t len,
+                       int depth,
+                       int do_store)
+{
+  struct ProcessResultClosure prc;
+  char enc[len];
+  struct GNUNET_CRYPTO_AesSessionKey sk;
+  struct GNUNET_CRYPTO_AesInitializationVector iv;
+  GNUNET_HashCode query;
+  
+  GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv);
+  if (-1 == GNUNET_CRYPTO_aes_encrypt (block, len,
+                                      &sk,
+                                      &iv,
+                                      enc))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+  GNUNET_CRYPTO_hash (enc, len, &query);
+  if (0 != memcmp (&query,
+                  &chk->query,
+                  sizeof (GNUNET_HashCode)))
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
+#if DEBUG_DOWNLOAD
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Matching block already present, no need for download!\n");
+#endif
+  /* already got it! */
+  prc.dc = dc;
+  prc.data = enc;
+  prc.size = len;
+  prc.type = (dc->treedepth == depth) 
+    ? GNUNET_BLOCK_TYPE_DBLOCK 
+    : GNUNET_BLOCK_TYPE_IBLOCK;
+  prc.query = chk->query;
+  prc.do_store = do_store;
+  process_result_with_request (&prc,
+                              &chk->key,
+                              sm);
+  return GNUNET_OK;
+}
 
+
 /**
+ * Closure for match_full_data.
+ */
+struct MatchDataContext 
+{
+  /**
+   * CHK we are looking for.
+   */
+  const struct ContentHashKey *chk;
+
+  /**
+   * Download we're processing.
+   */
+  struct GNUNET_FS_DownloadContext *dc;
+
+  /**
+   * Request details.
+   */
+  struct DownloadRequest *sm;
+
+  /**
+   * Overall offset in the file.
+   */
+  uint64_t offset;
+
+  /**
+   * Desired length of the block.
+   */
+  size_t len;
+
+  /**
+   * Flag set to GNUNET_YES on success.
+   */
+  int done;
+};
+
+/**
+ * Type of a function that libextractor calls for each
+ * meta data item found.
+ *
+ * @param cls closure (user-defined)
+ * @param plugin_name name of the plugin that produced this value;
+ *        special values can be used (i.e. '<zlib>' for zlib being
+ *        used in the main libextractor library and yielding
+ *        meta data).
+ * @param type libextractor-type describing the meta data
+ * @param format basic format information about data 
+ * @param data_mime_type mime-type of data (not of the original file);
+ *        can be NULL (if mime-type is not known)
+ * @param data actual meta-data found
+ * @param data_len number of bytes in data
+ * @return 0 to continue extracting, 1 to abort
+ */ 
+static int
+match_full_data (void *cls,
+                const char *plugin_name,
+                enum EXTRACTOR_MetaType type,
+                enum EXTRACTOR_MetaFormat format,
+                const char *data_mime_type,
+                const char *data,
+                size_t data_len)
+{
+  struct MatchDataContext *mdc = cls;
+  GNUNET_HashCode key;
+
+  if (type == EXTRACTOR_METATYPE_GNUNET_FULL_DATA) 
+    {
+      if ( (mdc->offset > data_len) ||
+          (mdc->offset + mdc->len > data_len) )
+       return 1;
+      GNUNET_CRYPTO_hash (&data[mdc->offset],
+                         mdc->len,
+                         &key);
+      if (0 != memcmp (&key,
+                      &mdc->chk->key,
+                      sizeof (GNUNET_HashCode)))
+       {
+         GNUNET_break_op (0);
+         return 1;
+       }
+      /* match found! */
+      if (GNUNET_OK !=
+         encrypt_existing_match (mdc->dc,
+                                 mdc->chk,
+                                 mdc->sm,
+                                 &data[mdc->offset],
+                                 mdc->len,
+                                 0,
+                                 GNUNET_YES))
+       {
+         GNUNET_break_op (0);
+         return 1;
+       }
+      mdc->done = GNUNET_YES;
+      return 1;
+    }
+  return 0;
+}
+
+
+/**
  * Schedule the download of the specified block in the tree.
  *
  * @param dc overall download this block belongs to
@@ -273,25 +438,18 @@
   size_t len;
   char block[DBLOCK_SIZE];
   GNUNET_HashCode key;
-  struct ProcessResultClosure prc;
+  struct MatchDataContext mdc;
   struct GNUNET_DISK_FileHandle *fh;
 
-#if DEBUG_DOWNLOAD
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Scheduling download at offset %llu and depth %u for `%s'\n",
-             (unsigned long long) offset,
-             depth,
-             GNUNET_h2s (&chk->query));
-#endif
   total = GNUNET_ntohll (dc->uri->data.chk.file_length);
+  len = GNUNET_FS_tree_calculate_block_size (total,
+                                            dc->treedepth,
+                                            offset,
+                                            depth);
   off = compute_disk_offset (total,
                             offset,
                             depth,
                             dc->treedepth);
-  len = GNUNET_FS_tree_calculate_block_size (total,
-                                            dc->treedepth,
-                                            offset,
-                                            depth);
   sm = GNUNET_malloc (sizeof (struct DownloadRequest));
   sm->chk = *chk;
   sm->offset = offset;
@@ -303,6 +461,29 @@
                                     &chk->query,
                                     sm,
                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+  if ( (dc->tried_full_data == GNUNET_NO) &&
+       (depth == 0) )
+    {      
+      mdc.dc = dc;
+      mdc.sm = sm;
+      mdc.chk = chk;
+      mdc.offset = offset;
+      mdc.len = len;
+      mdc.done = GNUNET_NO;
+      GNUNET_CONTAINER_meta_data_iterate (dc->meta,
+                                         &match_full_data,
+                                         &mdc);
+      if (mdc.done == GNUNET_YES)
+       return;
+      dc->tried_full_data = GNUNET_YES; 
+    }
+#if DEBUG_DOWNLOAD
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Scheduling download at offset %llu and depth %u for `%s'\n",
+             (unsigned long long) offset,
+             depth,
+             GNUNET_h2s (&chk->query));
+#endif
   fh = NULL;
   if ( (dc->old_file_size > off) &&
        (dc->filename != NULL) )    
@@ -320,55 +501,22 @@
                               len)) )
     {
       GNUNET_CRYPTO_hash (block, len, &key);
-      if (0 == memcmp (&key,
-                      &chk->key,
-                      sizeof (GNUNET_HashCode)))
+      if ( (0 == memcmp (&key,
+                        &chk->key,
+                        sizeof (GNUNET_HashCode))) &&
+          (GNUNET_OK ==
+           encrypt_existing_match (dc,
+                                   chk,
+                                   sm,
+                                   block,
+                                   len,
+                                   depth,
+                                   GNUNET_NO)) )
        {
-         char enc[len];
-         struct GNUNET_CRYPTO_AesSessionKey sk;
-         struct GNUNET_CRYPTO_AesInitializationVector iv;
-         GNUNET_HashCode query;
-
-         GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv);
-         if (-1 == GNUNET_CRYPTO_aes_encrypt (block, len,
-                                              &sk,
-                                              &iv,
-                                              enc))
-           {
-             GNUNET_break (0);
-             goto do_download;
-           }
-         GNUNET_CRYPTO_hash (enc, len, &query);
-         if (0 == memcmp (&query,
-                          &chk->query,
-                          sizeof (GNUNET_HashCode)))
-           {
-#if DEBUG_DOWNLOAD
-             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                         "Matching block already present, no need for 
download!\n");
-#endif
-             /* already got it! */
-             prc.dc = dc;
-             prc.data = enc;
-             prc.size = len;
-             prc.type = (dc->treedepth == depth) 
-               ? GNUNET_BLOCK_TYPE_DBLOCK 
-               : GNUNET_BLOCK_TYPE_IBLOCK;
-             prc.query = chk->query;
-             prc.do_store = GNUNET_NO; /* useless */
-             process_result_with_request (&prc,
-                                          &key,
-                                          sm);
-           }
-         else
-           {
-             GNUNET_break_op (0);
-           }
          GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
          return;
        }
     }
- do_download:
   if (fh != NULL)
     GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
   if (depth < dc->treedepth)

Modified: gnunet/src/include/gnunet_crypto_lib.h
===================================================================
--- gnunet/src/include/gnunet_crypto_lib.h      2010-07-16 15:31:37 UTC (rev 
12247)
+++ gnunet/src/include/gnunet_crypto_lib.h      2010-07-16 19:11:35 UTC (rev 
12248)
@@ -545,10 +545,8 @@
  * files does not exist, create a new key and write it to the
  * file.  Caller must free return value. Note that this function
  * can not guarantee that another process might not be trying
- * the same operation on the same file at the same time.  The
- * caller must somehow know that the file either already exists
- * with a valid key OR be sure that no other process is calling
- * this function at the same time.  If the contents of the file
+ * the same operation on the same file at the same time.  
+ * If the contents of the file
  * are invalid the old file is deleted and a fresh key is
  * created.
  *

Modified: gnunet/src/util/crypto_rsa.c
===================================================================
--- gnunet/src/util/crypto_rsa.c        2010-07-16 15:31:37 UTC (rev 12247)
+++ gnunet/src/util/crypto_rsa.c        2010-07-16 19:11:35 UTC (rev 12248)
@@ -546,10 +546,8 @@
  * files does not exist, create a new key and write it to the
  * file.  Caller must free return value.  Note that this function
  * can not guarantee that another process might not be trying
- * the same operation on the same file at the same time.  The
- * caller must somehow know that the file either already exists
- * with a valid key OR be sure that no other process is calling
- * this function at the same time.  If the contents of the file
+ * the same operation on the same file at the same time. 
+ * If the contents of the file
  * are invalid the old file is deleted and a fresh key is
  * created.
  *




reply via email to

[Prev in Thread] Current Thread [Next in Thread]