aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-27 11:14:19 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-27 11:14:19 +0000
commit57df0fbf8398720fbd4a9cf34934c212ea00ee54 (patch)
treea00d5740b2a35e21d4cff044c4ce941995b1bdff /src
parent2f7e69f969a822a38f9e311f79358e0fe8bda9d8 (diff)
downloadgnunet-57df0fbf8398720fbd4a9cf34934c212ea00ee54.tar.gz
gnunet-57df0fbf8398720fbd4a9cf34934c212ea00ee54.zip
syn
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs.h78
-rw-r--r--src/fs/fs_directory.c332
-rw-r--r--src/fs/fs_file_information.c3
-rw-r--r--src/fs/fs_publish.c853
-rw-r--r--src/include/gnunet_constants.h7
-rw-r--r--src/include/gnunet_container_lib.h27
-rw-r--r--src/include/gnunet_crypto_lib.h2
-rw-r--r--src/include/gnunet_datastore_service.h6
-rw-r--r--src/include/gnunet_fs_service.h46
-rw-r--r--src/util/container_meta_data.c32
-rw-r--r--src/util/crypto_hash.c2
11 files changed, 812 insertions, 576 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 4743a594b..c66249613 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -26,11 +26,33 @@
26#ifndef FS_H 26#ifndef FS_H
27#define FS_H 27#define FS_H
28 28
29#include "gnunet_datastore_service.h"
30#include "gnunet_fs_service.h"
31
29/** 32/**
30 * Size of the individual blocks used for file-sharing. 33 * Size of the individual blocks used for file-sharing.
31 */ 34 */
32#define GNUNET_FS_DBLOCK_SIZE (32*1024) 35#define GNUNET_FS_DBLOCK_SIZE (32*1024)
33 36
37
38/**
39 * Pick a multiple of 2 here to achive 8-byte alignment!
40 * We also probably want DBlocks to have (roughly) the
41 * same size as IBlocks. With SHA-512, the optimal
42 * value is 32768 byte / 128 byte = 256
43 * (128 byte = 2 * 512 bits). DO NOT CHANGE!
44 */
45#define GNUNET_FS_CHK_PER_INODE 256
46
47
48/**
49 * Maximum size for a file to be considered for
50 * inlining in a directory.
51 */
52#define GNUNET_FS_MAX_INLINE_SIZE 65536
53
54
55
34/** 56/**
35 * @brief content hash key 57 * @brief content hash key
36 */ 58 */
@@ -51,7 +73,7 @@ struct FileIdentifier
51 /** 73 /**
52 * Total size of the file in bytes. (network byte order (!)) 74 * Total size of the file in bytes. (network byte order (!))
53 */ 75 */
54 unsigned long long file_length; 76 uint64_t file_length;
55 77
56 /** 78 /**
57 * Query and key of the top GNUNET_EC_IBlock. 79 * Query and key of the top GNUNET_EC_IBlock.
@@ -187,6 +209,12 @@ struct GNUNET_FS_FileInformation
187 struct GNUNET_FS_Uri *keywords; 209 struct GNUNET_FS_Uri *keywords;
188 210
189 /** 211 /**
212 * CHK for this file or directory. NULL if
213 * we have not yet computed it.
214 */
215 struct GNUNET_FS_Uri *chk_uri;
216
217 /**
190 * At what time should the content expire? 218 * At what time should the content expire?
191 */ 219 */
192 struct GNUNET_TIME_Absolute expirationTime; 220 struct GNUNET_TIME_Absolute expirationTime;
@@ -198,6 +226,31 @@ struct GNUNET_FS_FileInformation
198 char *serialization; 226 char *serialization;
199 227
200 /** 228 /**
229 * In-memory cache of the current CHK tree.
230 * This struct will contain the CHK values
231 * from the root to the currently processed
232 * node in the tree as identified by
233 * "current_depth" and "publish_offset".
234 * The "chktree" will be initially NULL,
235 * then allocated to a sufficient number of
236 * entries for the size of the file and
237 * finally freed once the upload is complete.
238 */
239 struct ContentHashKey *chk_tree;
240
241 /**
242 * Number of entries in "chk_tree".
243 */
244 unsigned int chk_tree_depth;
245
246 /**
247 * Depth in the CHK-tree at which we are
248 * currently publishing. 0 is the root
249 * of the tree.
250 */
251 unsigned int current_depth;
252
253 /**
201 * How many bytes of this file or directory have been 254 * How many bytes of this file or directory have been
202 * published so far? 255 * published so far?
203 */ 256 */
@@ -257,6 +310,12 @@ struct GNUNET_FS_FileInformation
257 */ 310 */
258 uint64_t dir_size; 311 uint64_t dir_size;
259 312
313 /**
314 * Pointer to the data for the directory (or NULL if not
315 * available).
316 */
317 char *dir_data;
318
260 } dir; 319 } dir;
261 320
262 } data; 321 } data;
@@ -358,6 +417,23 @@ struct GNUNET_FS_PublishContext
358 * if the upload has completed. 417 * if the upload has completed.
359 */ 418 */
360 GNUNET_SCHEDULER_TaskIdentifier upload_task; 419 GNUNET_SCHEDULER_TaskIdentifier upload_task;
420
421 /**
422 * Current position in the file-tree for the
423 * upload.
424 */
425 struct GNUNET_FS_FileInformation *fi_pos;
426
427 /**
428 * Connection to the datastore service.
429 */
430 struct GNUNET_DATASTORE_Handle *dsh;
431
432 /**
433 * Space reservation ID with datastore service
434 * for this upload.
435 */
436 int rid;
361}; 437};
362 438
363 439
diff --git a/src/fs/fs_directory.c b/src/fs/fs_directory.c
index 3eb3af50d..e5a9f963f 100644
--- a/src/fs/fs_directory.c
+++ b/src/fs/fs_directory.c
@@ -25,7 +25,6 @@
25 * 25 *
26 * TODO: 26 * TODO:
27 * - add support for embedded file data (use padding room!) 27 * - add support for embedded file data (use padding room!)
28 * - add directory builder API to gnunet_fs_service
29 * - modify directory builder API to support incremental 28 * - modify directory builder API to support incremental
30 * generation of directories (to allow directories that 29 * generation of directories (to allow directories that
31 * would not fit into memory to be created) 30 * would not fit into memory to be created)
@@ -38,6 +37,9 @@
38#include "gnunet_fs_service.h" 37#include "gnunet_fs_service.h"
39#include "fs.h" 38#include "fs.h"
40 39
40#ifndef EXTRACTOR_GNUNET_FULL_DATA
41#define EXTRACTOR_GNUNET_FULL_DATA 137
42#endif
41 43
42/** 44/**
43 * Does the meta-data claim that this is a directory? 45 * Does the meta-data claim that this is a directory?
@@ -215,6 +217,7 @@ GNUNET_FS_directory_list_contents (size_t size,
215 return; /* malformed ! */ 217 return; /* malformed ! */
216 } 218 }
217 pos += mdSize; 219 pos += mdSize;
220 // EXTRACTOR_GNUNET_FULL_DATA
218 /* FIXME: add support for embedded data */ 221 /* FIXME: add support for embedded data */
219 filename = GNUNET_CONTAINER_meta_data_get_by_type (md, 222 filename = GNUNET_CONTAINER_meta_data_get_by_type (md,
220 EXTRACTOR_FILENAME); 223 EXTRACTOR_FILENAME);
@@ -231,14 +234,150 @@ GNUNET_FS_directory_list_contents (size_t size,
231 } 234 }
232} 235}
233 236
237/**
238 * Entries in the directory (builder).
239 */
240struct BuilderEntry
241{
242 /**
243 * This is a linked list.
244 */
245 struct BuilderEntry *next;
246
247 /**
248 * Length of this entry.
249 */
250 size_t len;
251};
234 252
235void 253/**
236GNUNET_FS_directory_create () 254 * Internal state of a directory builder.
255 */
256struct GNUNET_FS_DirectoryBuilder
237{ 257{
258 /**
259 * Meta-data for the directory itself.
260 */
261 struct GNUNET_CONTAINER_MetaData *meta;
262
263 /**
264 * Head of linked list of entries.
265 */
266 struct BuilderEntry *head;
267
268 /**
269 * Number of entires in the directory.
270 */
271 unsigned int count;
272};
273
274
275/**
276 * Create a directory builder.
277 *
278 * @param mdir metadata for the directory
279 */
280struct GNUNET_FS_DirectoryBuilder *
281GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir)
282{
283 struct GNUNET_FS_DirectoryBuilder *ret;
284
285 ret = GNUNET_malloc(sizeof(struct GNUNET_FS_DirectoryBuilder));
286 ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir);
287 GNUNET_FS_meta_data_make_directory (ret->meta);
288 return ret;
238} 289}
239 290
240 291
241#if 0 292/**
293 * Add an entry to a directory.
294 *
295 * @param bld directory to extend
296 * @param uri uri of the entry (must not be a KSK)
297 * @param md metadata of the entry
298 * @param data raw data of the entry, can be NULL, otherwise
299 * data must point to exactly the number of bytes specified
300 * by the uri which must be of type LOC or CHK
301 */
302void
303GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
304 const struct GNUNET_FS_Uri *uri,
305 const struct GNUNET_CONTAINER_MetaData *md,
306 const void *data)
307{
308 struct BuilderEntry *e;
309 uint64_t fsize;
310 uint32_t big;
311 size_t mds;
312 size_t mdxs;
313 char *uris;
314 char *ser;
315 size_t slen;
316 struct GNUNET_CONTAINER_MetaData *meta;
317 const struct GNUNET_CONTAINER_MetaData *meta_use;
318
319 GNUNET_assert (! GNUNET_FS_uri_ksk_test (uri));
320 if (NULL != data)
321 if (GNUNET_FS_uri_chk_test (uri))
322 fsize = GNUNET_FS_uri_chk_get_size (uri);
323 else
324 fsize = GNUNET_FS_uri_chk_get_size (GNUNET_FS_uri_loc_get_uri (uri));
325 else
326 fsize = 0; /* not given */
327 if (fsize > GNUNET_FS_MAX_INLINE_SIZE)
328 fsize = 0; /* too large */
329 if (memchr (data, fsize, '\0')) // FIXME: check memchr args!
330 fsize = 0; /* must not have 0's in data! */
331 uris = GNUNET_FS_uri_to_string (uri);
332 slen = strlen (uris) + 1;
333 mds =
334 GNUNET_CONTAINER_meta_data_get_serialized_size (md,
335 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
336 meta_use = md;
337 meta = NULL;
338 if (fsize > 0)
339 {
340 meta = GNUNET_CONTAINER_meta_data_duplicate (md);
341 GNUNET_CONTAINER_meta_data_insert (meta,
342 EXTRACTOR_GNUNET_FULL_DATA,
343 data);
344 mdxs =
345 GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
346 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
347 if ( (slen + sizeof (uint32_t) + mdxs - 1) / GNUNET_FS_DBLOCK_SIZE ==
348 (slen + sizeof (uint32_t) + mds - 1) / GNUNET_FS_DBLOCK_SIZE)
349 {
350 /* adding full data would not cause us to cross
351 additional blocks, so add it! */
352 meta_use = meta;
353 mds = mdxs;
354 }
355 }
356
357 if (mds > GNUNET_MAX_MALLOC_CHECKED / 2)
358 mds = GNUNET_MAX_MALLOC_CHECKED / 2;
359 e = GNUNET_malloc (sizeof(struct BuilderEntry) +
360 slen + mds + sizeof (uint32_t));
361 ser = (char*) &e[1];
362 memcpy (ser, uris, slen);
363 GNUNET_free (uris);
364 ret = GNUNET_CONTAINER_meta_data_serialize (meta_use,
365 &ser[slen + sizeof(uint32_t)],
366 mds,
367 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
368 if (NULL != meta)
369 GNUNET_CONTAINER_meta_data_destroy (meta);
370 if (ret == -1)
371 mds = 0;
372 else
373 mds = ret;
374 big = htonl (mds);
375 memcpy (&ser[slen], &big, sizeof (uint32_t));
376 e->len = slen + sizeof (uint32_t) + mds;
377 e->next = bld->head;
378 bld->head = e;
379 bld->count++;
380}
242 381
243 382
244/** 383/**
@@ -246,11 +385,11 @@ GNUNET_FS_directory_create ()
246 * data, return the end position of that data 385 * data, return the end position of that data
247 * after alignment to the GNUNET_FS_DBLOCK_SIZE. 386 * after alignment to the GNUNET_FS_DBLOCK_SIZE.
248 */ 387 */
249static uint64_t 388static size_t
250do_align (uint64_t start_position, 389do_align (size_t start_position,
251 uint64_t end_position) 390 size_t end_position)
252{ 391{
253 uint64_t align; 392 size_t align;
254 393
255 align = (end_position / GNUNET_FS_DBLOCK_SIZE) * GNUNET_FS_DBLOCK_SIZE; 394 align = (end_position / GNUNET_FS_DBLOCK_SIZE) * GNUNET_FS_DBLOCK_SIZE;
256 if ((start_position < align) && (end_position > align)) 395 if ((start_position < align) && (end_position > align))
@@ -269,19 +408,19 @@ do_align (uint64_t start_position,
269 * @param perm the permutation of the blocks (updated) 408 * @param perm the permutation of the blocks (updated)
270 */ 409 */
271static void 410static void
272block_align (uint64_t start, 411block_align (size_t start,
273 unsigned int count, 412 unsigned int count,
274 const uint64_t *sizes, 413 const size_t *sizes,
275 unsigned int *perm) 414 unsigned int *perm)
276{ 415{
277 unsigned int i; 416 unsigned int i;
278 unsigned int j; 417 unsigned int j;
279 unsigned int tmp; 418 unsigned int tmp;
280 unsigned int best; 419 unsigned int best;
281 int64_t badness; 420 ssize_t badness;
282 uint64_t cpos; 421 size_t cpos;
283 uint64_t cend; 422 size_t cend;
284 int64_t cbad; 423 ssize_t cbad;
285 unsigned int cval; 424 unsigned int cval;
286 425
287 cpos = start; 426 cpos = start;
@@ -334,135 +473,94 @@ block_align (uint64_t start,
334 473
335 474
336/** 475/**
337 * Create a directory. We allow packing more than one variable 476 * Finish building the directory. Frees the
338 * size entry into one block (and an entry could also span more 477 * builder context and returns the directory
339 * than one block), but an entry that is smaller than a single 478 * in-memory.
340 * block will never cross the block boundary. This is done to
341 * allow processing entries of a directory already even if the
342 * download is still partial.<p>
343 *
344 * The first block begins with the directories MAGIC signature,
345 * followed by the meta-data about the directory itself.<p>
346 * 479 *
347 * After that, the directory consists of block-aligned pairs 480 * @param bld directory to finish
348 * of URIs (0-terminated strings) and serialized meta-data. 481 * @param rsize set to the number of bytes needed
349 * 482 * @param rdata set to the encoded directory
350 * @param data pointer set to the beginning of the directory
351 * @param len set to number of bytes in data
352 * @param count number of entries in uris and mds
353 * @param uris URIs of the files in the directory
354 * @param mds meta-data for the files (must match
355 * respective values at same offset in in uris)
356 * @param mdir meta-data for the directory
357 * @return GNUNET_OK on success, GNUNET_SYSERR on error
358 */ 483 */
359int 484void
360GNUNET_FS_directory_create (char **data, 485GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
361 size_t *len, 486 size_t *rsize,
362 unsigned int count, 487 void **rdata)
363 const struct GNUNET_FS_Uri **uris,
364 const struct GNUNET_CONTAINER_MetaData **mds,
365 const struct GNUNET_CONTAINER_MetaData *mdir)
366{ 488{
489 char *data;
490 size_t *sizes;
491 unsigned int *perm;
367 unsigned int i; 492 unsigned int i;
368 unsigned int j; 493 unsigned int j;
369 uint64_t psize; 494 struct BuilderEntry *pos;
370 uint64_t size; 495 struct BuilderEntry **bes;
371 uint64_t pos; 496 size_t size;
372 char **ucs; 497 size_t psize;
373 int ret; 498 size_t off;
374 uint64_t *sizes; 499 ssize_t ret;
375 unsigned int *perm; 500 uint32_t big;
376 501
377 for (i = 0; i < count; i++) 502 size = 8 + sizeof (uint32_t);
378 { 503 size += GNUNET_meta_data_get_serialized_size (bld->meta,
379 if (GNUNET_FS_uri_test_ksk (fis[i].uri)) 504 GNUNET_SERIALIZE_FULL);
380 { 505 if (bld->count > 0)
381 GNUNET_break (0);
382 return GNUNET_SYSERR; /* illegal in directory! */
383 }
384 }
385 ucs = GNUNET_malloc (sizeof (char *) * count);
386 size = 8 + sizeof (unsigned int);
387 size += GNUNET_meta_data_get_serialized_size (meta, GNUNET_SERIALIZE_FULL);
388 sizes = GNUNET_malloc (count * sizeof (unsigned long long));
389 perm = GNUNET_malloc (count * sizeof (int));
390 for (i = 0; i < count; i++)
391 { 506 {
392 perm[i] = i; 507 sizes = GNUNET_malloc (bld->count * sizeof (size_t));
393 ucs[i] = GNUNET_FS_uri_to_string (fis[i].uri); 508 perm = GNUNET_malloc (bld->count * sizeof (unsigned int));
394 GNUNET_assert (ucs[i] != NULL); 509 bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *));
395 psize = 510 pos = bld->head;
396 GNUNET_meta_data_get_serialized_size (fis[i].meta, 511 for (i = 0; i < bld->count; i++)
397 GNUNET_SERIALIZE_FULL); 512 {
398 if (psize == -1) 513 perm[i] = i;
399 { 514 bes[i] = pos;
400 GNUNET_break (0); 515 sizes[i] = pos->size;
401 GNUNET_free (sizes); 516 pos = pos->next;
402 GNUNET_free (perm); 517 }
403 while (i >= 0) 518 }
404 GNUNET_free (ucs[i--]); 519 block_align (size,
405 GNUNET_free (ucs); 520 bld->count,
406 return GNUNET_SYSERR; 521 sizes,
407 } 522 perm);
408 sizes[i] = psize + sizeof (unsigned int) + strlen (ucs[i]) + 1;
409 }
410 /* permutate entries to minimize alignment cost */
411 block_align (size, count, sizes, perm);
412 523
413 /* compute final size with alignment */ 524 /* compute final size with alignment */
414 for (i = 0; i < count; i++) 525 for (i = 0; i < bld->count; i++)
415 { 526 {
416 psize = size; 527 psize = size;
417 size += sizes[perm[i]]; 528 size += sizes[perm[i]];
418 size = do_align (psize, size); 529 size = do_align (psize, size);
419 } 530 }
420 *len = size; 531 *rsize = size;
421 *data = GNUNET_malloc (size); 532 data = GNUNET_malloc (size);
422 memset (*data, 0, size); 533 *rdata = data;
423 534 memcpy (data, GNUNET_DIRECTORY_MAGIC, 8);
424 pos = 8; 535 off = 8;
425 memcpy (*data, GNUNET_DIRECTORY_MAGIC, 8);
426 536
427 ret = GNUNET_CONTAINER_meta_data_serialize (meta, 537 ret = GNUNET_CONTAINER_meta_data_serialize (meta,
428 &(*data)[pos + 538 &(*data)[off +
429 sizeof (unsigned int)], 539 sizeof (uint32_t)],
430 size - pos - sizeof (unsigned int), 540 size - pos - sizeof (uint32_t),
431 GNUNET_SERIALIZE_FULL); 541 GNUNET_SERIALIZE_FULL);
432 GNUNET_assert (ret != GNUNET_SYSERR); 542 GNUNET_assert (ret != -1);
433 ret = htonl (ret); 543 big = htonl (ret);
434 memcpy (&(*data)[pos], &ret, sizeof (unsigned int)); 544 memcpy (&(*data)[8], &big, sizeof (uint32_t));
435 pos += ntohl (ret) + sizeof (unsigned int); 545 pos += sizeof (uint32_t) + ret;
436
437 for (j = 0; j < count; j++) 546 for (j = 0; j < count; j++)
438 { 547 {
439 i = perm[j]; 548 i = perm[j];
440 psize = pos; 549 psize = pos;
441 pos += sizes[i]; 550 pos += sizes[i];
442 pos = do_align (psize, pos); 551 pos = do_align (psize, pos);
443 pos -= sizes[i]; /* go back to beginning */ 552 memcpy (&data[pos - sizes[i]],
444 memcpy (&(*data)[pos], ucs[i], strlen (ucs[i]) + 1); 553 &(bes[i])[1],
445 pos += strlen (ucs[i]) + 1; 554 sizes[i]);
446 GNUNET_free (ucs[i]); 555 GNUNET_free (bes[i]);
447 ret = GNUNET_CONTAINER_meta_data_serialize (mds[i],
448 &(*data)[pos +
449 sizeof (unsigned int)],
450 size - pos -
451 sizeof (unsigned int),
452 GNUNET_SERIALIZE_FULL);
453 GNUNET_assert (ret != GNUNET_SYSERR);
454 ret = htonl (ret);
455 memcpy (&(*data)[pos], &ret, sizeof (unsigned int));
456 pos += ntohl (ret) + sizeof (unsigned int);
457 } 556 }
458 GNUNET_free (sizes); 557 GNUNET_free (sizes);
459 GNUNET_free (perm); 558 GNUNET_free (perm);
460 GNUNET_free (ucs); 559 GNUNET_free (bes);
461 GNUNET_assert (pos == size); 560 GNUNET_assert (pos == size);
462 return GNUNET_OK; 561 GNUNET_CONTAINER_meta_data_destroy (bld->meta);
562 GNUNET_free (bld);
463} 563}
464 564
465 565
466#endif
467
468/* end of fs_directory.c */ 566/* end of fs_directory.c */
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c
index 540b518dc..60bcc2529 100644
--- a/src/fs/fs_file_information.c
+++ b/src/fs/fs_file_information.c
@@ -804,6 +804,7 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
804 &fi->priority, 804 &fi->priority,
805 &fi->expirationTime, 805 &fi->expirationTime,
806 &fi->client_info); 806 &fi->client_info);
807 GNUNET_free_non_null (fi->data.dir.dir_data);
807 GNUNET_free (fi->data.dir.dirname); 808 GNUNET_free (fi->data.dir.dirname);
808 } 809 }
809 else 810 else
@@ -821,7 +822,7 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
821 &fi->expirationTime, 822 &fi->expirationTime,
822 &fi->client_info); 823 &fi->client_info);
823 } 824 }
824 825 GNUNET_free_non_null (fi->chk_tree);
825 /* clean up serialization */ 826 /* clean up serialization */
826 if (0 != UNLINK (fi->serialization)) 827 if (0 != UNLINK (fi->serialization))
827 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 828 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 7696dd940..0078d0d32 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2009 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -24,15 +24,394 @@
24 * @see http://gnunet.org/encoding.php3 24 * @see http://gnunet.org/encoding.php3
25 * @author Krista Bennett 25 * @author Krista Bennett
26 * @author Christian Grothoff 26 * @author Christian Grothoff
27 *
28 * TODO:
29 * - directory creation
30 * - KBlocks
31 * - SBlocks
32 * - indexing support
33 * - calling of progress function
34 * - handling of IO errors (emsg)
35 * - code-sharing with unindex
36 * - datastore reservation support
37 * - persistence support
27 */ 38 */
28 39
29#include "platform.h" 40#include "platform.h"
41#include "gnunet_constants.h"
30#include "gnunet_util_lib.h" 42#include "gnunet_util_lib.h"
31#include "gnunet_fs_service.h" 43#include "gnunet_fs_service.h"
32#include "fs.h" 44#include "fs.h"
33 45
34#define DEBUG_PUBLISH GNUNET_YES 46#define DEBUG_PUBLISH GNUNET_YES
35 47
48/**
49 * Main function that performs the upload.
50 * @param cls "struct GNUNET_FS_PublishContext" identifies the upload
51 * @param tc task context
52 */
53static void
54do_upload (void *cls,
55 const struct GNUNET_SCHEDULER_TaskContext *tc);
56
57
58/**
59 * Context for "ds_put_cont".
60 */
61struct PutContCtx
62{
63 /**
64 * Publishing context for which the datastore
65 * PUT request was executed.
66 */
67 struct GNUNET_FS_PublishContext *sc;
68
69 /**
70 * Specific file with the block.
71 */
72 struct GNUNET_FS_FileInformation *p;
73
74 /**
75 * Function to run next, if any (can be NULL).
76 */
77 GNUNET_SCHEDULER_Task cont;
78};
79
80/**
81 * Function called by the datastore API with
82 * the result from the PUT request.
83 *
84 * @param cls our closure
85 * @param success GNUNET_OK on success
86 * @param msg error message (or NULL)
87 */
88static void
89ds_put_cont (void *cls,
90 int success,
91 const char *msg)
92{
93 struct PutContCtx *pcc = cls;
94
95 if (GNUNET_OK != success)
96 {
97 // FIXME: call progress CB with error
98 // FIXME: update pcc->p to indicate abort
99 GNUNET_FS_file_information_sync (pcc->p);
100 return;
101 }
102 GNUNET_FS_file_information_sync (pcc->p);
103 if (NULL != pcc->cont)
104 pcc->sc->upload_task
105 = GNUNET_SCHEDULER_add_delayed (pcc->sc->h->sched,
106 GNUNET_NO,
107 GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
108 GNUNET_SCHEDULER_NO_TASK,
109 GNUNET_TIME_UNIT_ZERO,
110 pcc->cont,
111 pcc->sc);
112 GNUNET_free (pcc);
113}
114
115
116/**
117 * We need to publish a specific block. Do it. Then continue with
118 * the main task.
119 *
120 * @param sc overall upload data
121 * @param p file that the block belongs to (needed for options!)
122 * @param blk encoded block to publish
123 * @param blk_size size of the block
124 * @param blk_type type of the block
125 * @param cont function to run when done
126 */
127static void
128publish_block (struct GNUNET_FS_PublishContext *sc,
129 struct GNUNET_FS_FileInformation *p,
130 const void* blk,
131 uint16_t blk_size,
132 uint32_t blk_type,
133 GNUNET_SCHEDULER_Task cont)
134{
135 struct GNUNET_HashCode key;
136
137 // FIXME: GNUNET_FS_get_key (blk_type, blk, blk_size, &key);
138 // (or add "key" as argument to reduce hashing?)
139 dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx));
140 dpc_cls->cont = cont;
141 dpc_cls->sc = sc;
142 dpc_cls->p = p;
143 // FIXME: need to do something to "sc" to mark
144 // that "sc" can not be freed right now due to this
145 // pending, scheduled operation for which we don't have
146 // a task ID!
147 GNUNET_DATASTORE_put (sc->dsh,
148 sc->rid,
149 &key,
150 blk_size,
151 blk_type,
152 p->priority,
153 p->anonymity,
154 p->expirationTime,
155 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
156 &ds_put_cont,
157 dpc_cls);
158}
159
160
161/**
162 * We are almost done publishing the structure,
163 * add SBlocks (if needed).
164 *
165 * @param sc overall upload data
166 */
167static void
168publish_sblock (struct GNUNET_FS_PublishContext *sc)
169{
170 struct GNUNET_FS_FileInformation *p;
171 p = sc->fi;
172
173 // FIXME: build sblock & call publish_block!
174
175 // FIXME: continuation should
176 // be releasing the datastore reserve
177 // (once implemented)
178}
179
180
181/**
182 * We have uploaded a file or directory; now publish
183 * the KBlocks in the global keyword space so that
184 * it can be found. Then continue with the
185 * main task.
186 *
187 * @param sc overall upload data
188 * @param p specific file or directory for which kblocks
189 * should be created
190 */
191static void
192publish_kblocks (struct GNUNET_FS_PublishContext *sc,
193 struct GNUNET_FS_FileInformation *p)
194{
195 // FIXME: build all kblocks
196 // call publish_kblock on each
197 // last continuation should then call the main continuation again
198}
199
200
201/**
202 * Compute the depth of the CHK tree.
203 *
204 * @param flen file length for which to compute the depth
205 * @return depth of the tree
206 */
207static unsigned int
208compute_depth (uint64_t flen)
209{
210 unsigned int treeDepth;
211 uint64_t fl;
212
213 treeDepth = 1;
214 fl = GNUNET_FS_DBLOCK_SIZE;
215 while (fl < flen)
216 {
217 treeDepth++;
218 if (fl * GNUNET_FS_CHK_PER_INODE < fl)
219 {
220 /* integer overflow, this is a HUGE file... */
221 return treeDepth;
222 }
223 fl = fl * GNUNET_FS_CHK_PER_INODE;
224 }
225 return treeDepth;
226}
227
228
229/**
230 * Compute the size of the current IBlock.
231 *
232 * @param height height of the IBlock in the tree (aka overall
233 * number of tree levels minus depth); 0 == DBlock
234 * @param offset current offset in the overall file
235 * @return size of the corresponding IBlock
236 */
237static uint16_t
238compute_iblock_size (unsigned int height,
239 uint64_t offset)
240{
241 unsigned int ret;
242 unsigned int i;
243 uint64_t mod;
244 uint64_t bds;
245
246 GNUNET_assert (height > 0);
247 bds = GNUNET_FS_DBLOCK_SIZE; /* number of bytes each CHK at level "i"
248 corresponds to */
249 for (i=0;i<height;i++)
250 bds *= GNUNET_FS_CHK_PER_INODE;
251 mod = offset % bds;
252 if (0 == mod)
253 {
254 /* we were triggered at the end of a full block */
255 ret = GNUNET_FS_CHK_PER_INODE;
256 }
257 else
258 {
259 /* we were triggered at the end of the file */
260 bds /= GNUNET_FS_CHK_PER_INODE;
261 ret = mod / bds;
262 if (0 != mod % bds)
263 ret++;
264 }
265 return (uint16_t) (ret * sizeof(struct ContentHashKey));
266}
267
268
269/**
270 * Compute the offset of the CHK for the
271 * current block in the IBlock above.
272 *
273 * @param height height of the IBlock in the tree (aka overall
274 * number of tree levels minus depth); 0 == DBlock
275 * @param offset current offset in the overall file
276 * @return (array of CHKs') offset in the above IBlock
277 */
278static unsigned int
279compute_chk_offset (unsigned int height,
280 uint64_t offset)
281{
282 uint64_t bds;
283 unsigned int ret;
284
285 bds = GNUNET_FS_DBLOCK_SIZE; /* number of bytes each CHK at level "i"
286 corresponds to */
287 for (i=0;i<height;i++)
288 bds *= GNUNET_FS_CHK_PER_INODE;
289 GNUNET_assert (0 == (offset % bds));
290 ret = offset / bds;
291 return ret % GNUNET_FS_CHK_PER_INODE;
292}
293
294
295/**
296 * We are uploading a file or directory; load (if necessary) the next
297 * block into memory, encrypt it and send it to the FS service. Then
298 * continue with the main task.
299 *
300 * @param sc overall upload data
301 * @param p specific file or directory for which kblocks
302 * should be created
303 */
304static void
305publish_content (struct GNUNET_FS_PublishContext *sc,
306 struct GNUNET_FS_FileInformation *p)
307{
308 struct ContentHashKey *chk;
309 const void *pt_block;
310 uint16_t pt_size;
311 char *emsg;
312 char iob[GNUNET_FS_DBLOCK_SIZE];
313 char enc[GNUNET_FS_DBLOCK_SIZE];
314 struct GNUNET_CRYPTO_AesSessionKey sk;
315 struct GNUNET_CRYPTO_AesInitializationVector iv;
316 uint64_t size;
317 unsigned int off;
318
319 // FIXME: figure out how to share this code
320 // with unindex!
321 size = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size;
322 if (NULL == p->chk_tree)
323 {
324 if (p->is_directory)
325 {
326 /* FIXME: create function to create directory
327 and use that API here! */
328 GNUNET_FS_directory_create (&p->data.dir.dir_size,
329 &p->data.dir.dir_data,
330 p->meta,
331 &directory_entry_lister,
332 p->data.dir.entries);
333 size = p->data.dir.data_size;
334 }
335 p->chk_tree_depth = compute_depth (size);
336 p->chk_tree = GNUNET_malloc (p->chk_tree_depth *
337 sizeof (struct ContentHashKey) *
338 GNUNET_FS_CHK_PER_INODE);
339 p->current_depth = p->chk_tree_depth;
340 }
341 if (p->current_depth == p->chk_tree_depth)
342 {
343 if (p->is_directory)
344 {
345 pt_size = GNUNET_MIN(GNUNET_FS_DBLOCK_SIZE,
346 p->data.dir.dir_size - p->publish_offset);
347 pt_block = &p->data.dir.dir_data[p->publish_offset];
348 }
349 else
350 {
351 pt_size = GNUNET_MIN(GNUNET_FS_DBLOCK_SIZE,
352 p->data.file.file_size - p->publish_offset);
353 p->data.file.reader (p->data.file.reader_cls,
354 p->publish_offset,
355 pt_size,
356 iob,
357 &emsg);
358 pt_block = iob;
359 }
360 }
361 else
362 {
363 pt_size = compute_iblock_size (p->chk_tree_depth - p->current_depth,
364 p->publish_offset);
365 pt_block = &p->chk_tree[p->current_depth *
366 GNUNET_FS_CHK_PER_INODE];
367 }
368 off = compute_chk_offset (p->chk_tree_depth - p->current_depth,
369 p->publish_offset);
370 chk = &p->chk_tree[(p->current_depth-1)*GNUNET_FS_CHK_PER_INODE+off];
371 GNUNET_CRYPTO_hash (pt_block, pt_size, &chk->key);
372 GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv);
373 GNUNET_CRYPTO_aes_encrypt (pt_block,
374 pt_size,
375 &sk,
376 &iv,
377 enc);
378 // NOTE: this call (and progress below) is all that really differs
379 // between publish/unindex! Parameterize & move this code!
380 // FIXME: something around here would need to change
381 // for indexing!
382 publish_block (sc, p, enc, pt_size,
383 (p->current_depth == p->chk_tree_depth)
384 ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK
385 : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK,
386 &do_upload);
387 // FIXME: should call progress function somewhere here!
388 GNUNET_CRYPTO_hash (enc, pt_size, &chk->query);
389 if (p->current_depth == p->chk_tree_depth)
390 {
391 p->publish_offset += pt_size;
392 if ( (p->publish_offset == size) ||
393 (0 == p->publish_offset % (GNUNET_FS_CHK_PER_INODE * GNUNET_FS_DBLOCK_SIZE) ) )
394 p->current_depth--;
395 }
396 else
397 {
398 if ( (off == GNUNET_FS_CHK_PER_INODE) ||
399 (p->publish_offset == size) )
400 p->current_depth--;
401 else
402 p->current_depth = p->chk_tree_depth;
403 }
404 if (0 == p->current_depth)
405 {
406 p->chk_uri = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri));
407 p->chk_uri.type = chk;
408 p->chk_uri.data.chk.chk = p->chk_tree[0];
409 p->chk_uri.data.chk.file_length = size;
410 GNUNET_free (p->chk_tree);
411 p->chk_tree = NULL;
412 }
413}
414
36 415
37/** 416/**
38 * Main function that performs the upload. 417 * Main function that performs the upload.
@@ -44,11 +423,36 @@ do_upload (void *cls,
44 const struct GNUNET_SCHEDULER_TaskContext *tc) 423 const struct GNUNET_SCHEDULER_TaskContext *tc)
45{ 424{
46 struct GNUNET_FS_PublishContext *sc = cls; 425 struct GNUNET_FS_PublishContext *sc = cls;
426 struct GNUNET_FS_FileInformation *p;
47 427
48 sc->upload_task = GNUNET_SCHEDULER_NO_TASK; 428 sc->upload_task = GNUNET_SCHEDULER_NO_TASK;
49 429 p = sc->fi_pos;
50 // FIXME: find next block, process, schedule 430 if (NULL == p)
51 // transmission to FS service 431 {
432 /* upload of entire hierarchy complete,
433 publish namespace entries */
434 publish_sblock (sc);
435 return;
436 }
437 if (NULL != p->chk_uri)
438 {
439 /* move on to next file */
440 if (NULL != p->next)
441 sc->fi_pos = p->next;
442 else
443 sc->fi_pos = p->dir;
444 /* upload of "p" complete, publish KBlocks! */
445 publish_kblocks (sc, p);
446 return;
447 }
448 if (p->do_index)
449 {
450 // FIXME: need to pre-compute hash over
451 // the entire file and ask FS to prepare
452 // for indexing!
453 return;
454 }
455 publish_content (sc, p);
52} 456}
53 457
54 458
@@ -75,8 +479,15 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
75 const char *nuid) 479 const char *nuid)
76{ 480{
77 struct GNUNET_FS_PublishContext *ret; 481 struct GNUNET_FS_PublishContext *ret;
482 struct GNUNET_FS_FileInformation *p;
483 struct GNUNET_DATASTORE_Handle *dsh;
78 484
485 dsh = GNUNET_DATASTORE_connect (h->cfg,
486 h->sched);
487 if (NULL == dsh)
488 return NULL;
79 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); 489 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext));
490 ret->dsh = dsh;
80 ret->h = h; 491 ret->h = h;
81 ret->client_ctx = ctx; 492 ret->client_ctx = ctx;
82 ret->fi = fi; 493 ret->fi = fi;
@@ -90,6 +501,17 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
90 ret->nuid = GNUNET_strdup (nuid); 501 ret->nuid = GNUNET_strdup (nuid);
91 } 502 }
92 // FIXME: make upload persistent! 503 // FIXME: make upload persistent!
504
505 /* find first leaf, DFS */
506 p = ret->fi;
507 while ( (p->is_directory) &&
508 (NULL != p->data.dir.entries) )
509 p = p->data.dir.entries;
510 ret->fi_pos = p;
511
512 // FIXME: calculate space needed for "fi"
513 // and reserve as first task (then trigger
514 // "do_upload" from that continuation)!
93 ret->upload_task 515 ret->upload_task
94 = GNUNET_SCHEDULER_add_delayed (h->sched, 516 = GNUNET_SCHEDULER_add_delayed (h->sched,
95 GNUNET_NO, 517 GNUNET_NO,
@@ -120,429 +542,8 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc)
120 GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO); 542 GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO);
121 GNUNET_free_non_null (sc->nid); 543 GNUNET_free_non_null (sc->nid);
122 GNUNET_free_non_null (sc->nuid); 544 GNUNET_free_non_null (sc->nuid);
545 GNUNET_DATASTORE_disconnect (sc->dsh);
123 GNUNET_free (sc); 546 GNUNET_free (sc);
124} 547}
125 548
126
127#if 0
128
129/**
130 * Append the given key and query to the iblock[level]. If
131 * iblock[level] is already full, compute its chk and push it to
132 * level+1 and clear the level. iblocks is guaranteed to be big
133 * enough.
134 */
135static int
136pushBlock (struct GNUNET_ClientServerConnection *sock,
137 const GNUNET_EC_ContentHashKey * chk,
138 unsigned int level,
139 GNUNET_DatastoreValue ** iblocks,
140 unsigned int prio, GNUNET_CronTime expirationTime)
141{
142 unsigned int size;
143 unsigned int present;
144 GNUNET_DatastoreValue *value;
145 GNUNET_EC_DBlock *db;
146 GNUNET_EC_ContentHashKey ichk;
147
148 size = ntohl (iblocks[level]->size);
149 GNUNET_GE_ASSERT (NULL, size > sizeof (GNUNET_DatastoreValue));
150 size -= sizeof (GNUNET_DatastoreValue);
151 GNUNET_GE_ASSERT (NULL,
152 size - sizeof (GNUNET_EC_DBlock) <=
153 GNUNET_ECRS_IBLOCK_SIZE);
154 present =
155 (size - sizeof (GNUNET_EC_DBlock)) / sizeof (GNUNET_EC_ContentHashKey);
156 db = (GNUNET_EC_DBlock *) & iblocks[level][1];
157 if (present == GNUNET_ECRS_CHK_PER_INODE)
158 {
159 GNUNET_EC_file_block_get_key (db, size, &ichk.key);
160 GNUNET_EC_file_block_get_query (db, size, &ichk.query);
161 if (GNUNET_OK != pushBlock (sock,
162 &ichk, level + 1, iblocks, prio,
163 expirationTime))
164 return GNUNET_SYSERR;
165 GNUNET_EC_file_block_encode (db, size, &ichk.query, &value);
166 if (value == NULL)
167 {
168 GNUNET_GE_BREAK (NULL, 0);
169 return GNUNET_SYSERR;
170 }
171 value->priority = htonl (prio);
172 value->expiration_time = GNUNET_htonll (expirationTime);
173 if (GNUNET_OK != GNUNET_FS_insert (sock, value))
174 {
175 GNUNET_free (value);
176 return GNUNET_SYSERR;
177 }
178 GNUNET_free (value);
179 size = sizeof (GNUNET_EC_DBlock); /* type */
180 }
181 /* append GNUNET_EC_ContentHashKey */
182 memcpy (&((char *) db)[size], chk, sizeof (GNUNET_EC_ContentHashKey));
183 size += sizeof (GNUNET_EC_ContentHashKey) + sizeof (GNUNET_DatastoreValue);
184 GNUNET_GE_ASSERT (NULL, size < GNUNET_MAX_BUFFER_SIZE);
185 iblocks[level]->size = htonl (size);
186
187 return GNUNET_OK;
188}
189
190/**
191 * Index or insert a file.
192 *
193 * @param priority what is the priority for OUR node to
194 * keep this file available? Use 0 for maximum anonymity and
195 * minimum reliability...
196 * @param doIndex GNUNET_YES for index, GNUNET_NO for insertion,
197 * GNUNET_SYSERR for simulation
198 * @param uri set to the URI of the uploaded file
199 * @return GNUNET_SYSERR if the upload failed (i.e. not enough space
200 * or gnunetd not running)
201 */
202int
203GNUNET_ECRS_file_upload (struct GNUNET_GE_Context *ectx,
204 struct GNUNET_GC_Configuration *cfg,
205 const char *filename,
206 int doIndex,
207 unsigned int anonymityLevel,
208 unsigned int priority,
209 GNUNET_CronTime expirationTime,
210 GNUNET_ECRS_UploadProgressCallback upcb,
211 void *upcbClosure,
212 GNUNET_ECRS_TestTerminate tt,
213 void *ttClosure, struct GNUNET_ECRS_URI **uri)
214{
215 unsigned long long filesize;
216 unsigned long long pos;
217 unsigned int treedepth;
218 int fd;
219 int i;
220 int ret;
221 unsigned int size;
222 GNUNET_DatastoreValue **iblocks;
223 GNUNET_DatastoreValue *dblock;
224 GNUNET_EC_DBlock *db;
225 GNUNET_DatastoreValue *value;
226 struct GNUNET_ClientServerConnection *sock;
227 GNUNET_HashCode fileId;
228 GNUNET_EC_ContentHashKey mchk;
229 GNUNET_CronTime eta;
230 GNUNET_CronTime start;
231 GNUNET_CronTime now;
232 GNUNET_EC_FileIdentifier fid;
233#if DEBUG_UPLOAD
234 GNUNET_EncName enc;
235#endif
236
237 GNUNET_GE_ASSERT (ectx, cfg != NULL);
238 start = GNUNET_get_time ();
239 memset (&mchk, 0, sizeof (GNUNET_EC_ContentHashKey));
240 if (GNUNET_YES != GNUNET_disk_file_test (ectx, filename))
241 {
242 GNUNET_GE_LOG (ectx,
243 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
244 _("`%s' is not a file.\n"), filename);
245 return GNUNET_SYSERR;
246 }
247 if (GNUNET_OK !=
248 GNUNET_disk_file_size (ectx, filename, &filesize, GNUNET_YES))
249 {
250 GNUNET_GE_LOG (ectx,
251 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
252 _("Cannot get size of file `%s'"), filename);
253
254 return GNUNET_SYSERR;
255 }
256 sock = GNUNET_client_connection_create (ectx, cfg);
257 if (sock == NULL)
258 {
259 GNUNET_GE_LOG (ectx,
260 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
261 _("Failed to connect to gnunetd."));
262 return GNUNET_SYSERR;
263 }
264 eta = 0;
265 if (upcb != NULL)
266 upcb (filesize, 0, eta, upcbClosure);
267 if (doIndex == GNUNET_YES)
268 {
269 if (GNUNET_SYSERR == GNUNET_hash_file (ectx, filename, &fileId))
270 {
271 GNUNET_GE_LOG (ectx,
272 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
273 _("Cannot hash `%s'.\n"), filename);
274
275 GNUNET_client_connection_destroy (sock);
276 return GNUNET_SYSERR;
277 }
278 if (GNUNET_YES == GNUNET_FS_test_indexed (sock, &fileId))
279 {
280 /* file already indexed; simulate only to get the URI! */
281 doIndex = GNUNET_SYSERR;
282 }
283 }
284 if (doIndex == GNUNET_YES)
285 {
286 now = GNUNET_get_time ();
287 eta = now + 2 * (now - start);
288 /* very rough estimate: GNUNET_hash reads once through the file,
289 we'll do that once more and write it. But of course
290 the second read may be cached, and we have the encryption,
291 so a factor of two is really, really just a rough estimate */
292 start = now;
293 /* reset the counter since the formula later does not
294 take the time for GNUNET_hash_file into account */
295
296 switch (GNUNET_FS_prepare_to_index (sock, &fileId, filename))
297 {
298 case GNUNET_SYSERR:
299 GNUNET_GE_LOG (ectx,
300 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
301 _("Initialization for indexing file `%s' failed.\n"),
302 filename);
303 GNUNET_client_connection_destroy (sock);
304 return GNUNET_SYSERR;
305 case GNUNET_NO:
306 GNUNET_GE_LOG (ectx,
307 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
308 _
309 ("Indexing file `%s' failed. Suggestion: try to insert the file.\n"),
310 filename);
311 GNUNET_client_connection_destroy (sock);
312 return GNUNET_SYSERR;
313 default:
314 break;
315 }
316 }
317 treedepth = GNUNET_ECRS_compute_depth (filesize);
318 fd = GNUNET_disk_file_open (ectx, filename, O_RDONLY | O_LARGEFILE);
319 if (fd == -1)
320 {
321 GNUNET_GE_LOG (ectx,
322 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
323 _("Cannot open file `%s': `%s'"), filename,
324 STRERROR (errno));
325
326 GNUNET_client_connection_destroy (sock);
327 return GNUNET_SYSERR;
328 }
329
330 dblock =
331 GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE +
332 sizeof (GNUNET_EC_DBlock));
333 dblock->size =
334 htonl (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE +
335 sizeof (GNUNET_EC_DBlock));
336 dblock->anonymity_level = htonl (anonymityLevel);
337 dblock->priority = htonl (priority);
338 dblock->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
339 dblock->expiration_time = GNUNET_htonll (expirationTime);
340 db = (GNUNET_EC_DBlock *) & dblock[1];
341 db->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
342 iblocks =
343 GNUNET_malloc (sizeof (GNUNET_DatastoreValue *) * (treedepth + 1));
344 for (i = 0; i <= treedepth; i++)
345 {
346 iblocks[i] =
347 GNUNET_malloc (sizeof (GNUNET_DatastoreValue) +
348 GNUNET_ECRS_IBLOCK_SIZE + sizeof (GNUNET_EC_DBlock));
349 iblocks[i]->size =
350 htonl (sizeof (GNUNET_DatastoreValue) + sizeof (GNUNET_EC_DBlock));
351 iblocks[i]->anonymity_level = htonl (anonymityLevel);
352 iblocks[i]->priority = htonl (priority);
353 iblocks[i]->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
354 iblocks[i]->expiration_time = GNUNET_htonll (expirationTime);
355 ((GNUNET_EC_DBlock *) & iblocks[i][1])->type =
356 htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
357 }
358
359 pos = 0;
360 while (pos < filesize)
361 {
362 if (upcb != NULL)
363 upcb (filesize, pos, eta, upcbClosure);
364 if (tt != NULL)
365 if (GNUNET_OK != tt (ttClosure))
366 goto FAILURE;
367 size = GNUNET_ECRS_DBLOCK_SIZE;
368 if (size > filesize - pos)
369 {
370 size = filesize - pos;
371 memset (&db[1], 0, GNUNET_ECRS_DBLOCK_SIZE);
372 }
373 GNUNET_GE_ASSERT (ectx,
374 sizeof (GNUNET_DatastoreValue) + size +
375 sizeof (GNUNET_EC_DBlock) < GNUNET_MAX_BUFFER_SIZE);
376 dblock->size =
377 htonl (sizeof (GNUNET_DatastoreValue) + size +
378 sizeof (GNUNET_EC_DBlock));
379 if (size != READ (fd, &db[1], size))
380 {
381 GNUNET_GE_LOG_STRERROR_FILE (ectx,
382 GNUNET_GE_ERROR | GNUNET_GE_BULK |
383 GNUNET_GE_ADMIN | GNUNET_GE_USER,
384 "READ", filename);
385 goto FAILURE;
386 }
387 if (tt != NULL)
388 if (GNUNET_OK != tt (ttClosure))
389 goto FAILURE;
390 GNUNET_EC_file_block_get_key (db, size + sizeof (GNUNET_EC_DBlock),
391 &mchk.key);
392 GNUNET_EC_file_block_get_query (db, size + sizeof (GNUNET_EC_DBlock),
393 &mchk.query);
394#if DEBUG_UPLOAD
395 GNUNET_hash_to_enc (&mchk.query, &enc);
396 fprintf (stderr,
397 "Query for current block of size %u is `%s'\n", size,
398 (const char *) &enc);
399#endif
400 if (doIndex == GNUNET_YES)
401 {
402 if (GNUNET_SYSERR == GNUNET_FS_index (sock, &fileId, dblock, pos))
403 {
404 GNUNET_GE_LOG (ectx,
405 GNUNET_GE_ERROR | GNUNET_GE_BULK |
406 GNUNET_GE_USER,
407 _
408 ("Indexing data of file `%s' failed at position %llu.\n"),
409 filename, pos);
410 goto FAILURE;
411 }
412 }
413 else
414 {
415 value = NULL;
416 if (GNUNET_OK !=
417 GNUNET_EC_file_block_encode (db,
418 size + sizeof (GNUNET_EC_DBlock),
419 &mchk.query, &value))
420 {
421 GNUNET_GE_BREAK (ectx, 0);
422 goto FAILURE;
423 }
424 GNUNET_GE_ASSERT (ectx, value != NULL);
425 *value = *dblock; /* copy options! */
426 if ((doIndex == GNUNET_NO) &&
427 (GNUNET_OK != (ret = GNUNET_FS_insert (sock, value))))
428 {
429 GNUNET_GE_BREAK (ectx, ret == GNUNET_NO);
430 GNUNET_free (value);
431 goto FAILURE;
432 }
433 GNUNET_free (value);
434 }
435 pos += size;
436 now = GNUNET_get_time ();
437 if (pos > 0)
438 {
439 eta = (GNUNET_CronTime) (start +
440 (((double) (now - start) / (double) pos))
441 * (double) filesize);
442 }
443 if (GNUNET_OK != pushBlock (sock, &mchk, 0, /* dblocks are on level 0 */
444 iblocks, priority, expirationTime))
445 goto FAILURE;
446 }
447 if (tt != NULL)
448 if (GNUNET_OK != tt (ttClosure))
449 goto FAILURE;
450#if DEBUG_UPLOAD
451 GNUNET_GE_LOG (ectx,
452 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
453 "Tree depth is %u, walking up tree.\n", treedepth);
454#endif
455 for (i = 0; i < treedepth; i++)
456 {
457 size = ntohl (iblocks[i]->size) - sizeof (GNUNET_DatastoreValue);
458 GNUNET_GE_ASSERT (ectx, size < GNUNET_MAX_BUFFER_SIZE);
459 if (size == sizeof (GNUNET_EC_DBlock))
460 {
461#if DEBUG_UPLOAD
462 GNUNET_GE_LOG (ectx,
463 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
464 "Level %u is empty\n", i);
465#endif
466 continue;
467 }
468 db = (GNUNET_EC_DBlock *) & iblocks[i][1];
469 GNUNET_EC_file_block_get_key (db, size, &mchk.key);
470#if DEBUG_UPLOAD
471 GNUNET_GE_LOG (ectx,
472 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
473 "Computing query for %u bytes content.\n", size);
474#endif
475 GNUNET_EC_file_block_get_query (db, size, &mchk.query);
476#if DEBUG_UPLOAD
477 IF_GELOG (ectx,
478 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
479 GNUNET_hash_to_enc (&mchk.query, &enc));
480 GNUNET_GE_LOG (ectx,
481 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
482 "Query for current block at level %u is `%s'.\n", i,
483 &enc);
484#endif
485 if (GNUNET_OK != pushBlock (sock,
486 &mchk, i + 1, iblocks, priority,
487 expirationTime))
488 {
489 GNUNET_GE_BREAK (ectx, 0);
490 goto FAILURE;
491 }
492 GNUNET_EC_file_block_encode (db, size, &mchk.query, &value);
493 if (value == NULL)
494 {
495 GNUNET_GE_BREAK (ectx, 0);
496 goto FAILURE;
497 }
498 value->expiration_time = GNUNET_htonll (expirationTime);
499 value->priority = htonl (priority);
500 if ((doIndex != GNUNET_SYSERR) &&
501 (GNUNET_SYSERR == GNUNET_FS_insert (sock, value)))
502 {
503 GNUNET_GE_BREAK (ectx, 0);
504 GNUNET_free (value);
505 goto FAILURE;
506 }
507 GNUNET_free (value);
508 GNUNET_free (iblocks[i]);
509 iblocks[i] = NULL;
510 }
511#if DEBUG_UPLOAD
512 IF_GELOG (ectx,
513 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
514 GNUNET_hash_to_enc (&mchk.query, &enc));
515 GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
516 "Query for top block is %s\n", &enc);
517#endif
518 /* build URI */
519 fid.file_length = GNUNET_htonll (filesize);
520 db = (GNUNET_EC_DBlock *) & iblocks[treedepth][1];
521
522 fid.chk = *(GNUNET_EC_ContentHashKey *) & (db[1]);
523 *uri = GNUNET_malloc (sizeof (URI));
524 (*uri)->type = chk;
525 (*uri)->data.fi = fid;
526
527 /* free resources */
528 GNUNET_free_non_null (iblocks[treedepth]);
529 GNUNET_free (iblocks);
530 GNUNET_free (dblock);
531 if (upcb != NULL)
532 upcb (filesize, filesize, eta, upcbClosure);
533 CLOSE (fd);
534 GNUNET_client_connection_destroy (sock);
535 return GNUNET_OK;
536FAILURE:
537 for (i = 0; i <= treedepth; i++)
538 GNUNET_free_non_null (iblocks[i]);
539 GNUNET_free (iblocks);
540 GNUNET_free (dblock);
541 CLOSE (fd);
542 GNUNET_client_connection_destroy (sock);
543 return GNUNET_SYSERR;
544}
545
546#endif
547
548/* end of fs_publish.c */ 549/* end of fs_publish.c */
diff --git a/src/include/gnunet_constants.h b/src/include/gnunet_constants.h
index 2c917cc59..bb122eb64 100644
--- a/src/include/gnunet_constants.h
+++ b/src/include/gnunet_constants.h
@@ -55,6 +55,13 @@ extern "C"
55 */ 55 */
56#define GNUNET_CONSTANTS_EXEC_WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100) 56#define GNUNET_CONSTANTS_EXEC_WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100)
57 57
58/**
59 * After how long do we consider a service irresponsive
60 * even if we assume that the service commonly does not
61 * respond instantly (DNS, Database, etc.).
62 */
63#define GNUNET_CONSTANTS_SERVICE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 10)
64
58 65
59#if 0 /* keep Emacsens' auto-indent happy */ 66#if 0 /* keep Emacsens' auto-indent happy */
60{ 67{
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
index 291b99fa2..e2a0787c8 100644
--- a/src/include/gnunet_container_lib.h
+++ b/src/include/gnunet_container_lib.h
@@ -305,8 +305,8 @@ int GNUNET_CONTAINER_meta_data_extract_from_file (struct
305 305
306enum GNUNET_CONTAINER_MetaDataSerializationOptions 306enum GNUNET_CONTAINER_MetaDataSerializationOptions
307{ 307{
308 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = GNUNET_NO, 308 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
309 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = GNUNET_YES, 309 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
310 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2 310 GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
311}; 311};
312 312
@@ -323,10 +323,11 @@ enum GNUNET_CONTAINER_MetaDataSerializationOptions
323 * GNUNET_SYSERR on error (typically: not enough 323 * GNUNET_SYSERR on error (typically: not enough
324 * space) 324 * space)
325 */ 325 */
326int GNUNET_CONTAINER_meta_data_serialize (const struct 326ssize_t GNUNET_CONTAINER_meta_data_serialize (const struct
327 GNUNET_CONTAINER_MetaData *md, 327 GNUNET_CONTAINER_MetaData *md,
328 char *target, unsigned int size, 328 char *target,
329 enum 329 size_t size,
330 enum
330 GNUNET_CONTAINER_MetaDataSerializationOptions 331 GNUNET_CONTAINER_MetaDataSerializationOptions
331 opt); 332 opt);
332 333
@@ -337,12 +338,12 @@ int GNUNET_CONTAINER_meta_data_serialize (const struct
337 * meta-data to match the size constraint, 338 * meta-data to match the size constraint,
338 * possibly discarding some data? 339 * possibly discarding some data?
339 */ 340 */
340unsigned int GNUNET_CONTAINER_meta_data_get_serialized_size (const struct 341ssize_t GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
341 GNUNET_CONTAINER_MetaData 342 GNUNET_CONTAINER_MetaData
342 *md, 343 *md,
343 enum 344 enum
344 GNUNET_CONTAINER_MetaDataSerializationOptions 345 GNUNET_CONTAINER_MetaDataSerializationOptions
345 opt); 346 opt);
346 347
347/** 348/**
348 * Deserialize meta-data. Initializes md. 349 * Deserialize meta-data. Initializes md.
@@ -352,7 +353,7 @@ unsigned int GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
352 */ 353 */
353struct GNUNET_CONTAINER_MetaData 354struct GNUNET_CONTAINER_MetaData
354 *GNUNET_CONTAINER_meta_data_deserialize (const char *input, 355 *GNUNET_CONTAINER_meta_data_deserialize (const char *input,
355 unsigned int size); 356 size_t size);
356 357
357/** 358/**
358 * Does the meta-data claim that this is a directory? 359 * Does the meta-data claim that this is a directory?
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 361d244e2..168c79b2a 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -394,7 +394,7 @@ void GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
394/** 394/**
395 * Convert a hashcode into a key. 395 * Convert a hashcode into a key.
396 */ 396 */
397void GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc, 397void GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
398 struct GNUNET_CRYPTO_AesSessionKey *skey, 398 struct GNUNET_CRYPTO_AesSessionKey *skey,
399 struct 399 struct
400 GNUNET_CRYPTO_AesInitializationVector 400 GNUNET_CRYPTO_AesInitializationVector
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
index 28419126f..3805dea97 100644
--- a/src/include/gnunet_datastore_service.h
+++ b/src/include/gnunet_datastore_service.h
@@ -41,6 +41,12 @@ extern "C"
41#endif 41#endif
42#endif 42#endif
43 43
44#define GNUNET_DATASTORE_BLOCKTYPE_ANY 0
45#define GNUNET_DATASTORE_BLOCKTYPE_DBLOCK 1
46#define GNUNET_DATASTORE_BLOCKTYPE_IBLOCK 2
47#define GNUNET_DATASTORE_BLOCKTYPE_KBLOCK 3
48#define GNUNET_DATASTORE_BLOCKTYPE_SBLOCK 4
49#define GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK 5
44 50
45/** 51/**
46 * Handle to the datastore service. 52 * Handle to the datastore service.
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 4664c4cee..3c71d40e7 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -2169,6 +2169,52 @@ GNUNET_FS_directory_list_contents (size_t size,
2169 void *dep_cls); 2169 void *dep_cls);
2170 2170
2171 2171
2172/**
2173 * Opaque handle to a directory builder.
2174 */
2175struct GNUNET_FS_DirectoryBuilder;
2176
2177/**
2178 * Create a directory builder.
2179 *
2180 * @param mdir metadata for the directory
2181 */
2182struct GNUNET_FS_DirectoryBuilder *
2183GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir);
2184
2185
2186/**
2187 * Add an entry to a directory.
2188 *
2189 * @param bld directory to extend
2190 * @param uri uri of the entry (must not be a KSK)
2191 * @param md metadata of the entry
2192 * @param data raw data of the entry, can be NULL, otherwise
2193 * data must point to exactly the number of bytes specified
2194 * by the uri
2195 */
2196void
2197GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
2198 const struct GNUNET_FS_Uri *uri,
2199 const struct GNUNET_CONTAINER_MetaData *md,
2200 const void *data);
2201
2202
2203/**
2204 * Finish building the directory. Frees the
2205 * builder context and returns the directory
2206 * in-memory.
2207 *
2208 * @param bld directory to finish
2209 * @param size set to the number of bytes needed
2210 * @param data set to the encoded directory
2211 */
2212void
2213GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
2214 size_t *size,
2215 void **data);
2216
2217
2172#if 0 /* keep Emacsens' auto-indent happy */ 2218#if 0 /* keep Emacsens' auto-indent happy */
2173{ 2219{
2174#endif 2220#endif
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c
index 6265fc142..d80c5fd2b 100644
--- a/src/util/container_meta_data.c
+++ b/src/util/container_meta_data.c
@@ -442,9 +442,9 @@ struct MetaDataHeader
442 * GNUNET_SYSERR on error (typically: not enough 442 * GNUNET_SYSERR on error (typically: not enough
443 * space) 443 * space)
444 */ 444 */
445int 445ssize_t
446GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData 446GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
447 *md, char *target, unsigned int max, 447 *md, char *target, size_t max,
448 enum 448 enum
449 GNUNET_CONTAINER_MetaDataSerializationOptions 449 GNUNET_CONTAINER_MetaDataSerializationOptions
450 part) 450 part)
@@ -463,7 +463,7 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
463 while (1) 463 while (1)
464 { 464 {
465 size = sizeof (struct MetaDataHeader); 465 size = sizeof (struct MetaDataHeader);
466 size += sizeof (unsigned int) * ic; 466 size += sizeof (uint32_t) * ic;
467 for (i = 0; i < ic; i++) 467 for (i = 0; i < ic; i++)
468 size += 1 + strlen (md->items[i].data); 468 size += 1 + strlen (md->items[i].data);
469 while (size % 8 != 0) 469 while (size % 8 != 0)
@@ -472,8 +472,8 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
472 hdr->version = htonl (md == NULL ? 1 : 0); 472 hdr->version = htonl (md == NULL ? 1 : 0);
473 hdr->entries = htonl (ic); 473 hdr->entries = htonl (ic);
474 for (i = 0; i < ic; i++) 474 for (i = 0; i < ic; i++)
475 ((unsigned int *) &hdr[1])[i] = 475 ((uint32_t *) &hdr[1])[i] =
476 htonl ((unsigned int) md->items[i].type); 476 htonl ((uint32_t) md->items[i].type);
477 pos = sizeof (struct MetaDataHeader); 477 pos = sizeof (struct MetaDataHeader);
478 pos += sizeof (unsigned int) * ic; 478 pos += sizeof (unsigned int) * ic;
479 for (i = 0; i < ic; i++) 479 for (i = 0; i < ic; i++)
@@ -533,7 +533,7 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
533 * serialized form. The estimate MAY be higher 533 * serialized form. The estimate MAY be higher
534 * than what is strictly needed. 534 * than what is strictly needed.
535 */ 535 */
536unsigned int 536ssize_t
537GNUNET_CONTAINER_meta_data_get_serialized_size (const struct 537GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
538 GNUNET_CONTAINER_MetaData *md, 538 GNUNET_CONTAINER_MetaData *md,
539 enum 539 enum
@@ -549,7 +549,7 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
549 549
550 ic = md ? md->itemCount : 0; 550 ic = md ? md->itemCount : 0;
551 size = sizeof (struct MetaDataHeader); 551 size = sizeof (struct MetaDataHeader);
552 size += sizeof (unsigned int) * ic; 552 size += sizeof (uint32_t) * ic;
553 for (i = 0; i < ic; i++) 553 for (i = 0; i < ic; i++)
554 size += 1 + strlen (md->items[i].data); 554 size += 1 + strlen (md->items[i].data);
555 while (size % 8 != 0) 555 while (size % 8 != 0)
@@ -558,9 +558,9 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
558 hdr->version = htonl (md == NULL ? 1 : 0); 558 hdr->version = htonl (md == NULL ? 1 : 0);
559 hdr->entries = htonl (ic); 559 hdr->entries = htonl (ic);
560 for (i = 0; i < ic; i++) 560 for (i = 0; i < ic; i++)
561 ((unsigned int *) &hdr[1])[i] = htonl ((unsigned int) md->items[i].type); 561 ((uint32_t *) &hdr[1])[i] = htonl ((uint32_t) md->items[i].type);
562 pos = sizeof (struct MetaDataHeader); 562 pos = sizeof (struct MetaDataHeader);
563 pos += sizeof (unsigned int) * ic; 563 pos += sizeof (uint32_t) * ic;
564 for (i = 0; i < ic; i++) 564 for (i = 0; i < ic; i++)
565 { 565 {
566 len = strlen (md->items[i].data) + 1; 566 len = strlen (md->items[i].data) + 1;
@@ -590,7 +590,7 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
590 * bad format) 590 * bad format)
591 */ 591 */
592struct GNUNET_CONTAINER_MetaData * 592struct GNUNET_CONTAINER_MetaData *
593GNUNET_CONTAINER_meta_data_deserialize (const char *input, unsigned int size) 593GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size)
594{ 594{
595 struct GNUNET_CONTAINER_MetaData *md; 595 struct GNUNET_CONTAINER_MetaData *md;
596 const struct MetaDataHeader *hdr; 596 const struct MetaDataHeader *hdr;
@@ -599,9 +599,9 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, unsigned int size)
599 const char *cdata; 599 const char *cdata;
600 uint32_t dataSize; 600 uint32_t dataSize;
601 int compressed; 601 int compressed;
602 int i; 602 uint32_t i;
603 unsigned int pos; 603 size_t pos;
604 int len; 604 size_t len;
605 uint32_t version; 605 uint32_t version;
606 606
607 if (size < sizeof (struct MetaDataHeader)) 607 if (size < sizeof (struct MetaDataHeader))
@@ -651,7 +651,7 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, unsigned int size)
651 } 651 }
652 } 652 }
653 653
654 if ((sizeof (unsigned int) * ic + ic) > dataSize) 654 if ((sizeof (uint32_t) * ic + ic) > dataSize)
655 { 655 {
656 GNUNET_break (0); 656 GNUNET_break (0);
657 goto FAILURE; 657 goto FAILURE;
@@ -665,12 +665,12 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, unsigned int size)
665 md = GNUNET_CONTAINER_meta_data_create (); 665 md = GNUNET_CONTAINER_meta_data_create ();
666 GNUNET_array_grow (md->items, md->itemCount, ic); 666 GNUNET_array_grow (md->items, md->itemCount, ic);
667 i = 0; 667 i = 0;
668 pos = sizeof (unsigned int) * ic; 668 pos = sizeof (uint32_t) * ic;
669 while ((pos < dataSize) && (i < ic)) 669 while ((pos < dataSize) && (i < ic))
670 { 670 {
671 len = strlen (&cdata[pos]) + 1; 671 len = strlen (&cdata[pos]) + 1;
672 md->items[i].type = (EXTRACTOR_KeywordType) 672 md->items[i].type = (EXTRACTOR_KeywordType)
673 ntohl (MAKE_UNALIGNED (((const unsigned int *) cdata)[i])); 673 ntohl (MAKE_UNALIGNED (((const uint32_t *) cdata)[i]));
674 md->items[i].data = GNUNET_strdup (&cdata[pos]); 674 md->items[i].data = GNUNET_strdup (&cdata[pos]);
675 pos += len; 675 pos += len;
676 i++; 676 i++;
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index fc4d24320..a8843b5b7 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -709,7 +709,7 @@ GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
709 * Convert a hashcode into a key. 709 * Convert a hashcode into a key.
710 */ 710 */
711void 711void
712GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc, 712GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
713 struct GNUNET_CRYPTO_AesSessionKey *skey, 713 struct GNUNET_CRYPTO_AesSessionKey *skey,
714 struct GNUNET_CRYPTO_AesInitializationVector 714 struct GNUNET_CRYPTO_AesInitializationVector
715 *iv) 715 *iv)