aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-30 13:46:28 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-30 13:46:28 +0000
commit5cf21b88fb81906c3da589495da11291d5c12d35 (patch)
treef573ce1a0d67926753ff2f3a24e15ee621bc3eb1 /src
parentcabc8ba699f76cab751b97014d9375ec74612448 (diff)
downloadgnunet-5cf21b88fb81906c3da589495da11291d5c12d35.tar.gz
gnunet-5cf21b88fb81906c3da589495da11291d5c12d35.zip
kblocks
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs.h34
-rw-r--r--src/fs/fs_publish.c662
-rw-r--r--src/fs/gnunet-publish.c7
3 files changed, 586 insertions, 117 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 66190a42d..f0d9718a2 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -445,6 +445,11 @@ struct GNUNET_FS_PublishContext
445 int in_network_wait; 445 int in_network_wait;
446 446
447 /** 447 /**
448 * Options for publishing.
449 */
450 enum GNUNET_FS_PublishOptions options;
451
452 /**
448 * Current position in the file-tree for the 453 * Current position in the file-tree for the
449 * upload. 454 * upload.
450 */ 455 */
@@ -495,4 +500,33 @@ struct GNUNET_FS_Namespace
495}; 500};
496 501
497 502
503/**
504 * @brief keyword block (advertising data under a keyword)
505 */
506struct GNUNET_FS_KBlock
507{
508
509 /**
510 * GNUNET_RSA_Signature using RSA-key generated from search keyword.
511 */
512 struct GNUNET_CRYPTO_RsaSignature signature;
513
514 /**
515 * What is being signed and why?
516 */
517 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
518
519 /**
520 * Key generated (!) from the H(keyword) as the seed!
521 */
522 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded keyspace;
523
524 /* 0-terminated URI here */
525
526 /* variable-size Meta-Data follows here */
527
528};
529
498#endif 530#endif
531
532/* end of fs.h */
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 124f73743..b9bf1dc9c 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -26,7 +26,6 @@
26 * @author Christian Grothoff 26 * @author Christian Grothoff
27 * 27 *
28 * TODO: 28 * TODO:
29 * - KBlocks
30 * - SBlocks 29 * - SBlocks
31 * - indexing support 30 * - indexing support
32 * - code-sharing with unindex (can wait) 31 * - code-sharing with unindex (can wait)
@@ -36,12 +35,15 @@
36 35
37#include "platform.h" 36#include "platform.h"
38#include "gnunet_constants.h" 37#include "gnunet_constants.h"
38#include "gnunet_signatures.h"
39#include "gnunet_util_lib.h" 39#include "gnunet_util_lib.h"
40#include "gnunet_fs_service.h" 40#include "gnunet_fs_service.h"
41#include "fs.h" 41#include "fs.h"
42 42
43#define DEBUG_PUBLISH GNUNET_YES 43#define DEBUG_PUBLISH GNUNET_YES
44 44
45#define MAX_KBLOCK_SIZE 60000
46
45/** 47/**
46 * Main function that performs the upload. 48 * Main function that performs the upload.
47 * @param cls "struct GNUNET_FS_PublishContext" identifies the upload 49 * @param cls "struct GNUNET_FS_PublishContext" identifies the upload
@@ -58,8 +60,7 @@ do_upload (void *cls,
58struct PutContCtx 60struct PutContCtx
59{ 61{
60 /** 62 /**
61 * Publishing context for which the datastore 63 * Current publishing context.
62 * PUT request was executed.
63 */ 64 */
64 struct GNUNET_FS_PublishContext *sc; 65 struct GNUNET_FS_PublishContext *sc;
65 66
@@ -72,6 +73,11 @@ struct PutContCtx
72 * Function to run next, if any (can be NULL). 73 * Function to run next, if any (can be NULL).
73 */ 74 */
74 GNUNET_SCHEDULER_Task cont; 75 GNUNET_SCHEDULER_Task cont;
76
77 /**
78 * Closure for cont.
79 */
80 void *cont_cls;
75}; 81};
76 82
77 83
@@ -173,56 +179,12 @@ ds_put_cont (void *cls,
173 GNUNET_SCHEDULER_NO_TASK, 179 GNUNET_SCHEDULER_NO_TASK,
174 GNUNET_TIME_UNIT_ZERO, 180 GNUNET_TIME_UNIT_ZERO,
175 pcc->cont, 181 pcc->cont,
176 pcc->sc); 182 pcc->cont_cls);
177 GNUNET_free (pcc); 183 GNUNET_free (pcc);
178} 184}
179 185
180 186
181/** 187/**
182 * We need to publish a specific block. Do it. Then continue with
183 * the main task.
184 *
185 * @param sc overall upload data
186 * @param p file that the block belongs to (needed for options!)
187 * @param query what the block should be indexed under
188 * @param blk encoded block to publish
189 * @param blk_size size of the block
190 * @param blk_type type of the block
191 * @param cont function to run when done
192 */
193static void
194publish_block (struct GNUNET_FS_PublishContext *sc,
195 struct GNUNET_FS_FileInformation *p,
196 const GNUNET_HashCode *query,
197 const void* blk,
198 uint16_t blk_size,
199 uint32_t blk_type,
200 GNUNET_SCHEDULER_Task cont)
201{
202 struct PutContCtx * dpc_cls;
203
204 dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx));
205 dpc_cls->cont = cont;
206 dpc_cls->sc = sc;
207 dpc_cls->p = p;
208 GNUNET_assert (GNUNET_NO == sc->in_network_wait);
209 sc->in_network_wait = GNUNET_YES;
210 GNUNET_DATASTORE_put (sc->dsh,
211 sc->rid,
212 query,
213 blk_size,
214 blk,
215 blk_type,
216 p->priority,
217 p->anonymity,
218 p->expirationTime,
219 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
220 &ds_put_cont,
221 dpc_cls);
222}
223
224
225/**
226 * Generate the callback that signals clients 188 * Generate the callback that signals clients
227 * that a file (or directory) has been completely 189 * that a file (or directory) has been completely
228 * published. 190 * published.
@@ -247,6 +209,59 @@ signal_publish_completion (struct GNUNET_FS_FileInformation *p,
247 209
248 210
249/** 211/**
212 * Generate the callback that signals clients
213 * that a file (or directory) has encountered
214 * a problem during publication.
215 *
216 * @param p the upload that had trouble
217 * @param sc context of the publication
218 * @param emsg error message
219 */
220static void
221signal_publish_error (struct GNUNET_FS_FileInformation *p,
222 struct GNUNET_FS_PublishContext *sc,
223 const char *emsg)
224{
225 struct GNUNET_FS_ProgressInfo pi;
226
227 p->emsg = GNUNET_strdup (emsg);
228 pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR;
229 make_publish_status (&pi, sc, p);
230 pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
231 pi.value.publish.specifics.error.message =emsg;
232 p->client_info
233 = sc->h->upcb (sc->h->upcb_cls,
234 &pi);
235}
236
237
238/**
239 * We've finished publishing the SBlock as part of a larger upload.
240 * Check the result and complete the larger upload.
241 *
242 * @param cls the "struct GNUNET_FS_PublishContext*" of the larger upload
243 * @param uri URI of the published SBlock
244 * @param emsg NULL on success, otherwise error message
245 */
246static void
247publish_sblocks_cont (void *cls,
248 const struct GNUNET_FS_Uri *uri,
249 const char *emsg)
250{
251 struct GNUNET_FS_PublishContext *sc = cls;
252 if (NULL != emsg)
253 {
254 signal_publish_error (sc->fi,
255 sc,
256 emsg);
257 return;
258 }
259 // FIXME: release the datastore reserve here!
260 signal_publish_completion (sc->fi, sc);
261}
262
263
264/**
250 * We are almost done publishing the structure, 265 * We are almost done publishing the structure,
251 * add SBlocks (if needed). 266 * add SBlocks (if needed).
252 * 267 *
@@ -255,52 +270,63 @@ signal_publish_completion (struct GNUNET_FS_FileInformation *p,
255static void 270static void
256publish_sblock (struct GNUNET_FS_PublishContext *sc) 271publish_sblock (struct GNUNET_FS_PublishContext *sc)
257{ 272{
258 struct GNUNET_FS_FileInformation *p;
259 p = sc->fi;
260
261 if (NULL != sc->namespace) 273 if (NULL != sc->namespace)
262 GNUNET_FS_publish_sks (sc->h, 274 GNUNET_FS_publish_sks (sc->h,
263 sc->namespace, 275 sc->namespace,
264 sc->nid, 276 sc->nid,
265 sc->nuid, 277 sc->nuid,
266 p->meta, 278 sc->fi->meta,
267 p->chk_uri, 279 sc->fi->chk_uri,
268 p->expirationTime, 280 sc->fi->expirationTime,
269 p->anonymity, 281 sc->fi->anonymity,
270 p->priority); 282 sc->fi->priority,
271 // FIXME: release the datastore reserve here! 283 sc->options,
272 signal_publish_completion (p, sc); 284 &publish_sblocks_cont,
285 sc);
286 else
287 publish_sblocks_cont (sc, NULL, NULL);
273} 288}
274 289
275 290
276/** 291/**
277 * We have uploaded a file or directory; now publish 292 * We've finished publishing a KBlock
278 * the KBlocks in the global keyword space so that 293 * as part of a larger upload. Check
279 * it can be found. Then continue with the 294 * the result and continue the larger
280 * main task. 295 * upload.
281 * 296 *
282 * @param sc overall upload data 297 * @param cls the "struct GNUNET_FS_PublishContext*" of the larger upload
283 * @param p specific file or directory for which kblocks 298 * @param uri URI of the published blocks
284 * should be created 299 * @param emsg NULL on success, otherwise error message
285 */ 300 */
286static void 301static void
287publish_kblocks (struct GNUNET_FS_PublishContext *sc, 302publish_kblocks_cont (void *cls,
288 struct GNUNET_FS_FileInformation *p) 303 const struct GNUNET_FS_Uri *uri,
304 const char *emsg)
289{ 305{
290 unsigned int i; 306 struct GNUNET_FS_PublishContext *sc = cls;
307 struct GNUNET_FS_FileInformation *p = sc->fi_pos;
291 308
292 // FIXME: use cps here instead... 309 if (NULL != emsg)
293 for (i=0;i<p->keywords->data.ksk.keywordCount;i++) 310 {
294 GNUNET_FS_publish_ksk (sc->h, 311 signal_publish_error (p, sc, emsg);
295 p->keywords->data.ksk.keywords[i], 312 sc->upload_task
296 p->meta, 313 = GNUNET_SCHEDULER_add_delayed (sc->h->sched,
297 p->chk_uri, 314 GNUNET_NO,
298 p->expirationTime, 315 GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
299 p->anonymity, 316 GNUNET_SCHEDULER_NO_TASK,
300 p->priority); 317 GNUNET_TIME_UNIT_ZERO,
318 &do_upload,
319 sc);
320 return;
321 }
301 GNUNET_FS_file_information_sync (p); 322 GNUNET_FS_file_information_sync (p);
302 if (NULL != p->dir) 323 if (NULL != p->dir)
303 signal_publish_completion (p, sc); 324 signal_publish_completion (p, sc);
325 /* move on to next file */
326 if (NULL != p->next)
327 sc->fi_pos = p->next;
328 else
329 sc->fi_pos = p->dir;
304 sc->upload_task 330 sc->upload_task
305 = GNUNET_SCHEDULER_add_delayed (sc->h->sched, 331 = GNUNET_SCHEDULER_add_delayed (sc->h->sched,
306 GNUNET_NO, 332 GNUNET_NO,
@@ -435,6 +461,7 @@ publish_content (struct GNUNET_FS_PublishContext *sc,
435 struct GNUNET_FS_FileInformation *dirpos; 461 struct GNUNET_FS_FileInformation *dirpos;
436 void *raw_data; 462 void *raw_data;
437 char *dd; 463 char *dd;
464 struct PutContCtx * dpc_cls;
438 465
439 // FIXME: figure out how to share this code 466 // FIXME: figure out how to share this code
440 // with unindex! 467 // with unindex!
@@ -473,7 +500,7 @@ publish_content (struct GNUNET_FS_PublishContext *sc,
473 } 500 }
474 } 501 }
475 } 502 }
476 GNUNET_FS_directory_builder_add (db, 503 GNUNET_FS_directory_builder_add (db,
477 dirpos->chk_uri, 504 dirpos->chk_uri,
478 dirpos->meta, 505 dirpos->meta,
479 raw_data); 506 raw_data);
@@ -555,18 +582,44 @@ publish_content (struct GNUNET_FS_PublishContext *sc,
555 &sk, 582 &sk,
556 &iv, 583 &iv,
557 enc); 584 enc);
558 // NOTE: this call (and progress below) is all that really differs 585 // NOTE: this block below is all that really differs
559 // between publish/unindex! Parameterize & move this code! 586 // between publish/unindex! Parameterize & move this code!
560 // FIXME: something around here would need to change 587 // FIXME: something around here would need to change
561 // for indexing! 588 // for indexing!
562 publish_block (sc, p, 589 if (NULL == sc->dsh)
563 &mychk->query, 590 {
564 enc, 591 sc->upload_task
565 pt_size, 592 = GNUNET_SCHEDULER_add_delayed (sc->h->sched,
566 (p->current_depth == p->chk_tree_depth) 593 GNUNET_NO,
567 ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK 594 GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
568 : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK, 595 GNUNET_SCHEDULER_NO_TASK,
569 &do_upload); 596 GNUNET_TIME_UNIT_ZERO,
597 &do_upload,
598 sc);
599 }
600 else
601 {
602 GNUNET_assert (GNUNET_NO == sc->in_network_wait);
603 sc->in_network_wait = GNUNET_YES;
604 dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx));
605 dpc_cls->cont = &do_upload;
606 dpc_cls->cont_cls = sc;
607 dpc_cls->p = p;
608 GNUNET_DATASTORE_put (sc->dsh,
609 sc->rid,
610 &mychk->query,
611 pt_size,
612 enc,
613 (p->current_depth == p->chk_tree_depth)
614 ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK
615 : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK,
616 p->priority,
617 p->anonymity,
618 p->expirationTime,
619 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
620 &ds_put_cont,
621 dpc_cls);
622 }
570 if (p->current_depth == p->chk_tree_depth) 623 if (p->current_depth == p->chk_tree_depth)
571 { 624 {
572 pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; 625 pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
@@ -629,6 +682,16 @@ do_upload (void *cls,
629 publish_sblock (sc); 682 publish_sblock (sc);
630 return; 683 return;
631 } 684 }
685 /* find starting position */
686 while ( (p->is_directory) &&
687 (NULL != p->data.dir.entries) &&
688 (NULL == p->emsg) &&
689 (NULL == p->data.dir.entries->chk_uri) )
690 {
691 p = p->data.dir.entries;
692 sc->fi_pos = p;
693 }
694 /* abort on error */
632 if (NULL != p->emsg) 695 if (NULL != p->emsg)
633 { 696 {
634 /* error with current file, abort all 697 /* error with current file, abort all
@@ -653,15 +716,20 @@ do_upload (void *cls,
653 } 716 }
654 return; 717 return;
655 } 718 }
719 /* handle completion */
656 if (NULL != p->chk_uri) 720 if (NULL != p->chk_uri)
657 { 721 {
658 /* move on to next file */
659 if (NULL != p->next)
660 sc->fi_pos = p->next;
661 else
662 sc->fi_pos = p->dir;
663 /* upload of "p" complete, publish KBlocks! */ 722 /* upload of "p" complete, publish KBlocks! */
664 publish_kblocks (sc, p); 723 GNUNET_FS_publish_ksk (sc->h,
724 p->keywords,
725 p->meta,
726 p->chk_uri,
727 p->expirationTime,
728 p->anonymity,
729 p->priority,
730 sc->options,
731 &publish_kblocks_cont,
732 sc);
665 return; 733 return;
666 } 734 }
667 if ( (!p->is_directory) && 735 if ( (!p->is_directory) &&
@@ -725,6 +793,7 @@ fip_signal_start(void *cls,
725 * (can be NULL, must be NULL if namespace is NULL) 793 * (can be NULL, must be NULL if namespace is NULL)
726 * @param nuid update-identifier that will be used for future updates 794 * @param nuid update-identifier that will be used for future updates
727 * (can be NULL, must be NULL if namespace or nid is NULL) 795 * (can be NULL, must be NULL if namespace or nid is NULL)
796 * @param options options for the publication
728 * @return context that can be used to control the publish operation 797 * @return context that can be used to control the publish operation
729 */ 798 */
730struct GNUNET_FS_PublishContext * 799struct GNUNET_FS_PublishContext *
@@ -733,16 +802,23 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
733 struct GNUNET_FS_FileInformation *fi, 802 struct GNUNET_FS_FileInformation *fi,
734 struct GNUNET_FS_Namespace *namespace, 803 struct GNUNET_FS_Namespace *namespace,
735 const char *nid, 804 const char *nid,
736 const char *nuid) 805 const char *nuid,
806 enum GNUNET_FS_PublishOptions options)
737{ 807{
738 struct GNUNET_FS_PublishContext *ret; 808 struct GNUNET_FS_PublishContext *ret;
739 struct GNUNET_FS_FileInformation *p;
740 struct GNUNET_DATASTORE_Handle *dsh; 809 struct GNUNET_DATASTORE_Handle *dsh;
741 810
742 dsh = GNUNET_DATASTORE_connect (h->cfg, 811 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
743 h->sched); 812 {
744 if (NULL == dsh) 813 dsh = GNUNET_DATASTORE_connect (h->cfg,
745 return NULL; 814 h->sched);
815 if (NULL == dsh)
816 return NULL;
817 }
818 else
819 {
820 dsh = NULL;
821 }
746 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); 822 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext));
747 ret->dsh = dsh; 823 ret->dsh = dsh;
748 ret->h = h; 824 ret->h = h;
@@ -763,12 +839,7 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
763 GNUNET_FS_file_information_inspect (ret->fi, 839 GNUNET_FS_file_information_inspect (ret->fi,
764 &fip_signal_start, 840 &fip_signal_start,
765 ret); 841 ret);
766 /* find first leaf, DFS */ 842 ret->fi_pos = ret->fi;
767 p = ret->fi;
768 while ( (p->is_directory) &&
769 (NULL != p->data.dir.entries) )
770 p = p->data.dir.entries;
771 ret->fi_pos = p;
772 843
773 // FIXME: calculate space needed for "fi" 844 // FIXME: calculate space needed for "fi"
774 // and reserve as first task (then trigger 845 // and reserve as first task (then trigger
@@ -851,29 +922,293 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc)
851 922
852 923
853/** 924/**
854 * Publish a KBlock on GNUnet. 925 * Context for the KSK publication.
926 */
927struct PublishKskContext
928{
929
930 /**
931 * Keywords to use.
932 */
933 struct GNUNET_FS_Uri *ksk_uri;
934
935 /**
936 * Global FS context.
937 */
938 struct GNUNET_FS_Handle *h;
939
940 /**
941 * The master block that we are sending
942 * (in plaintext), has "mdsize+slen" more
943 * bytes than the struct would suggest.
944 */
945 struct GNUNET_FS_KBlock *kb;
946
947 /**
948 * Buffer of the same size as "kb" for
949 * the encrypted version.
950 */
951 struct GNUNET_FS_KBlock *cpy;
952
953 /**
954 * Handle to the datastore, NULL if we are just
955 * simulating.
956 */
957 struct GNUNET_DATASTORE_Handle *dsh;
958
959 /**
960 * Function to call once we're done.
961 */
962 GNUNET_FS_PublishContinuation cont;
963
964 /**
965 * Closure for cont.
966 */
967 void *cont_cls;
968
969 /**
970 * When should the KBlocks expire?
971 */
972 struct GNUNET_TIME_Absolute expirationTime;
973
974 /**
975 * Size of the serialized metadata.
976 */
977 ssize_t mdsize;
978
979 /**
980 * Size of the (CHK) URI as a string.
981 */
982 size_t slen;
983
984 /**
985 * Keyword that we are currently processing.
986 */
987 unsigned int i;
988
989 /**
990 * Anonymity level for the KBlocks.
991 */
992 unsigned int anonymity;
993
994 /**
995 * Priority for the KBlocks.
996 */
997 unsigned int priority;
998};
999
1000
1001/**
1002 * Continuation of "GNUNET_FS_publish_ksk" that performs
1003 * the actual publishing operation (iterating over all
1004 * of the keywords).
1005 *
1006 * @param cls closure of type "struct PublishKskContext*"
1007 * @param tc unused
1008 */
1009static void
1010publish_ksk_cont (void *cls,
1011 const struct GNUNET_SCHEDULER_TaskContext *tc);
1012
1013
1014/**
1015 * Function called by the datastore API with
1016 * the result from the PUT request.
1017 *
1018 * @param cls closure of type "struct PublishKskContext*"
1019 * @param success GNUNET_OK on success
1020 * @param msg error message (or NULL)
1021 */
1022static void
1023kb_put_cont (void *cls,
1024 int success,
1025 const char *msg)
1026{
1027 struct PublishKskContext *pkc = cls;
1028
1029 if (GNUNET_OK != success)
1030 {
1031 GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
1032 GNUNET_free (pkc->cpy);
1033 GNUNET_free (pkc->kb);
1034 pkc->cont (pkc->cont_cls,
1035 NULL,
1036 msg);
1037 GNUNET_FS_uri_destroy (pkc->ksk_uri);
1038 GNUNET_free (pkc);
1039 return;
1040 }
1041 GNUNET_SCHEDULER_add_continuation (pkc->h->sched,
1042 GNUNET_NO,
1043 &publish_ksk_cont,
1044 pkc,
1045 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
1046}
1047
1048
1049/**
1050 * Continuation of "GNUNET_FS_publish_ksk" that performs
1051 * the actual publishing operation (iterating over all
1052 * of the keywords).
1053 *
1054 * @param cls closure of type "struct PublishKskContext*"
1055 * @param tc unused
1056 */
1057static void
1058publish_ksk_cont (void *cls,
1059 const struct GNUNET_SCHEDULER_TaskContext *tc)
1060{
1061 struct PublishKskContext *pkc = cls;
1062 const char *keyword;
1063 GNUNET_HashCode key;
1064 GNUNET_HashCode query;
1065 struct GNUNET_CRYPTO_AesSessionKey skey;
1066 struct GNUNET_CRYPTO_AesInitializationVector iv;
1067 struct GNUNET_CRYPTO_RsaPrivateKey *pk;
1068
1069
1070 if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) ||
1071 (NULL == pkc->dsh) )
1072 {
1073 if (NULL != pkc->dsh)
1074 GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
1075 GNUNET_free (pkc->cpy);
1076 GNUNET_free (pkc->kb);
1077 pkc->cont (pkc->cont_cls,
1078 pkc->ksk_uri,
1079 NULL);
1080 GNUNET_FS_uri_destroy (pkc->ksk_uri);
1081 GNUNET_free (pkc);
1082 return;
1083 }
1084 keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
1085 /* first character of keyword indicates if it is
1086 mandatory or not -- ignore for hashing */
1087 GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key);
1088 GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
1089 GNUNET_CRYPTO_aes_encrypt (&pkc->kb[1],
1090 pkc->slen + pkc->mdsize,
1091 &skey,
1092 &iv,
1093 &pkc->cpy[1]);
1094 pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key);
1095 GNUNET_CRYPTO_rsa_key_get_public (pk, &pkc->cpy->keyspace);
1096 GNUNET_CRYPTO_hash (&pkc->cpy->keyspace,
1097 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1098 &query);
1099 GNUNET_assert (GNUNET_OK ==
1100 GNUNET_CRYPTO_rsa_sign (pk,
1101 &pkc->cpy->purpose,
1102 &pkc->cpy->signature));
1103 GNUNET_CRYPTO_rsa_key_free (pk);
1104 GNUNET_DATASTORE_put (pkc->dsh,
1105 0,
1106 &query,
1107 pkc->mdsize +
1108 sizeof (struct GNUNET_FS_KBlock) +
1109 pkc->slen,
1110 pkc->cpy,
1111 GNUNET_DATASTORE_BLOCKTYPE_KBLOCK,
1112 pkc->priority,
1113 pkc->anonymity,
1114 pkc->expirationTime,
1115 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
1116 &kb_put_cont,
1117 pkc);
1118}
1119
1120
1121/**
1122 * Publish a CHK under various keywords on GNUnet.
855 * 1123 *
856 * @param h handle to the file sharing subsystem 1124 * @param h handle to the file sharing subsystem
857 * @param keyword keyword to use 1125 * @param ksk_uri keywords to use
858 * @param meta metadata to use 1126 * @param meta metadata to use
859 * @param uri URI to refer to in the KBlock 1127 * @param uri URI to refer to in the KBlock
860 * @param expirationTime when the KBlock expires 1128 * @param expirationTime when the KBlock expires
861 * @param anonymity anonymity level for the KBlock 1129 * @param anonymity anonymity level for the KBlock
862 * @param priority priority for the KBlock 1130 * @param priority priority for the KBlock
1131 * @param options publication options
1132 * @param cont continuation
1133 * @param cont_cls closure for cont
863 */ 1134 */
864// FIXME: cps this one
865void 1135void
866GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, 1136GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
867 const char *keyword, 1137 struct GNUNET_FS_Uri *ksk_uri,
868 struct GNUNET_CONTAINER_MetaData *meta, 1138 struct GNUNET_CONTAINER_MetaData *meta,
869 struct GNUNET_FS_Uri *uri, 1139 struct GNUNET_FS_Uri *uri,
870 struct GNUNET_TIME_Absolute expirationTime, 1140 struct GNUNET_TIME_Absolute expirationTime,
871 unsigned int anonymity, 1141 unsigned int anonymity,
872 unsigned int priority) 1142 unsigned int priority,
1143 enum GNUNET_FS_PublishOptions options,
1144 GNUNET_FS_PublishContinuation cont,
1145 void *cont_cls)
873{ 1146{
874 // FIXME! 1147 struct PublishKskContext *pkc;
875} 1148 char *uris;
1149 size_t size;
1150 char *kbe;
1151
1152 pkc = GNUNET_malloc (sizeof (struct PublishKskContext));
1153 pkc->h = h;
1154 pkc->expirationTime = expirationTime;
1155 pkc->anonymity = anonymity;
1156 pkc->priority = priority;
1157 pkc->cont = cont;
1158 pkc->cont_cls = cont_cls;
1159 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
1160 {
1161 pkc->dsh = GNUNET_DATASTORE_connect (h->cfg,
1162 h->sched);
1163 if (pkc->dsh == NULL)
1164 {
1165 cont (cont_cls, NULL, _("Could not connect to datastore."));
1166 GNUNET_free (pkc);
1167 return;
1168 }
1169 }
1170 pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
1171 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
1172 GNUNET_assert (pkc->mdsize >= 0);
1173 uris = GNUNET_FS_uri_to_string (uri);
1174 pkc->slen = strlen (uris) + 1;
1175 size = pkc->mdsize + sizeof (struct GNUNET_FS_KBlock) + pkc->slen;
1176 if (size > MAX_KBLOCK_SIZE)
1177 {
1178 size = MAX_KBLOCK_SIZE;
1179 pkc->mdsize = size - sizeof (struct GNUNET_FS_KBlock) - pkc->slen;
1180 }
1181 pkc->kb = GNUNET_malloc (size);
1182 kbe = (char *) &pkc->kb[1];
1183 memcpy (kbe, uris, pkc->slen);
1184 GNUNET_free (uris);
1185 pkc->mdsize = GNUNET_CONTAINER_meta_data_serialize (meta,
1186 &kbe[pkc->slen],
1187 pkc->mdsize,
1188 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
1189 if (pkc->mdsize == -1)
1190 {
1191 GNUNET_break (0);
1192 GNUNET_free (uris);
1193 GNUNET_free (pkc->kb);
1194 if (pkc->dsh != NULL)
1195 GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
1196 cont (cont_cls, NULL, _("Internal error."));
1197 GNUNET_free (pkc);
1198 return;
1199 }
1200 size = sizeof (struct GNUNET_FS_KBlock) + pkc->slen + pkc->mdsize;
876 1201
1202 pkc->cpy = GNUNET_malloc (size);
1203 pkc->cpy->purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + pkc->mdsize + pkc->slen);
1204 pkc->cpy->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK);
1205 pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
1206 GNUNET_SCHEDULER_add_continuation (h->sched,
1207 GNUNET_NO,
1208 &publish_ksk_cont,
1209 pkc,
1210 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
1211}
877 1212
878 1213
879/** 1214/**
@@ -888,8 +1223,10 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
888 * @param expirationTime when the SBlock expires 1223 * @param expirationTime when the SBlock expires
889 * @param anonymity anonymity level for the SBlock 1224 * @param anonymity anonymity level for the SBlock
890 * @param priority priority for the SBlock 1225 * @param priority priority for the SBlock
1226 * @param options publication options
1227 * @param cont continuation
1228 * @param cont_cls closure for cont
891 */ 1229 */
892// FIXME: cps this one
893void 1230void
894GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, 1231GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
895 struct GNUNET_FS_Namespace *namespace, 1232 struct GNUNET_FS_Namespace *namespace,
@@ -899,9 +1236,104 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
899 struct GNUNET_FS_Uri *uri, 1236 struct GNUNET_FS_Uri *uri,
900 struct GNUNET_TIME_Absolute expirationTime, 1237 struct GNUNET_TIME_Absolute expirationTime,
901 unsigned int anonymity, 1238 unsigned int anonymity,
902 unsigned int priority) 1239 unsigned int priority,
1240 enum GNUNET_FS_PublishOptions options,
1241 GNUNET_FS_PublishContinuation cont,
1242 void *cont_cls)
903{ 1243{
904 // FIXME 1244#if 0
1245 struct GNUNET_ECRS_URI *uri;
1246 struct GNUNET_ClientServerConnection *sock;
1247 GNUNET_DatastoreValue *value;
1248 unsigned int size;
1249 unsigned int mdsize;
1250 struct GNUNET_RSA_PrivateKey *hk;
1251 GNUNET_EC_SBlock *sb;
1252 char *dstURI;
1253 char *destPos;
1254 GNUNET_HashCode hc; /* hash of thisId = key */
1255 GNUNET_HashCode hc2; /* hash of hc = identifier */
1256 int ret;
1257 unsigned int nidlen;
1258
1259 hk = read_namespace_key (cfg, pid);
1260 if (hk == NULL)
1261 return NULL;
1262
1263 /* THEN: construct GNUNET_EC_SBlock */
1264 dstURI = GNUNET_ECRS_uri_to_string (dstU);
1265 mdsize = GNUNET_meta_data_get_serialized_size (md, GNUNET_SERIALIZE_PART);
1266 if (nextId == NULL)
1267 nextId = "";
1268 nidlen = strlen (nextId) + 1;
1269 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen;
1270 if (size > MAX_SBLOCK_SIZE)
1271 {
1272 size = MAX_SBLOCK_SIZE;
1273 mdsize =
1274 size - (sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen);
1275 }
1276 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
1277 sb = (GNUNET_EC_SBlock *) & value[1];
1278 sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
1279 destPos = (char *) &sb[1];
1280 memcpy (destPos, nextId, nidlen);
1281 destPos += nidlen;
1282 memcpy (destPos, dstURI, strlen (dstURI) + 1);
1283 destPos += strlen (dstURI) + 1;
1284 mdsize = GNUNET_meta_data_serialize (ectx,
1285 md,
1286 destPos,
1287 mdsize, GNUNET_SERIALIZE_PART);
1288 if (mdsize == -1)
1289 {
1290 GNUNET_GE_BREAK (ectx, 0);
1291 GNUNET_free (dstURI);
1292 GNUNET_RSA_free_key (hk);
1293 GNUNET_free (value);
1294 return NULL;
1295 }
1296 size = sizeof (GNUNET_EC_SBlock) + mdsize + strlen (dstURI) + 1 + nidlen;
1297 value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
1298 value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
1299 value->priority = htonl (priority);
1300 value->anonymity_level = htonl (anonymityLevel);
1301 value->expiration_time = GNUNET_htonll (expiration);
1302 GNUNET_hash (thisId, strlen (thisId), &hc);
1303 GNUNET_hash (&hc, sizeof (GNUNET_HashCode), &hc2);
1304 uri = GNUNET_malloc (sizeof (URI));
1305 uri->type = sks;
1306 GNUNET_RSA_get_public_key (hk, &sb->subspace);
1307 GNUNET_hash (&sb->subspace,
1308 sizeof (GNUNET_RSA_PublicKey), &uri->data.sks.namespace);
1309 GNUNET_GE_BREAK (ectx, 0 == memcmp (&uri->data.sks.namespace,
1310 pid, sizeof (GNUNET_HashCode)));
1311 uri->data.sks.identifier = GNUNET_strdup (thisId);
1312 GNUNET_hash_xor (&hc2, &uri->data.sks.namespace, &sb->identifier);
1313 GNUNET_ECRS_encryptInPlace (&hc, &sb[1], size - sizeof (GNUNET_EC_SBlock));
1314 GNUNET_GE_ASSERT (ectx,
1315 GNUNET_OK == GNUNET_RSA_sign (hk,
1316 size
1317 -
1318 sizeof
1319 (GNUNET_RSA_Signature) -
1320 sizeof
1321 (GNUNET_RSA_PublicKey) -
1322 sizeof (unsigned int),
1323 &sb->identifier,
1324 &sb->signature));
1325 GNUNET_RSA_free_key (hk);
1326 sock = GNUNET_client_connection_create (ectx, cfg);
1327 ret = GNUNET_FS_insert (sock, value);
1328 if (ret != GNUNET_OK)
1329 {
1330 GNUNET_free (uri);
1331 uri = NULL;
1332 }
1333 GNUNET_client_connection_destroy (sock);
1334 GNUNET_free (value);
1335 GNUNET_free (dstURI);
1336#endif
905} 1337}
906 1338
907/* end of fs_publish.c */ 1339/* end of fs_publish.c */
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index 7aac35146..b6b9199d0 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -26,7 +26,7 @@
26 * @author Igor Wronsky 26 * @author Igor Wronsky
27 * 27 *
28 * TODO: 28 * TODO:
29 * - support for some options is still missing (uri argument, simulate) 29 * - support for some options is still missing (uri argument)
30 * - progress callbacks not implemented (and need verbosity option) 30 * - progress callbacks not implemented (and need verbosity option)
31 * - clean shutdown is not implemented (stop ctx, etc.) 31 * - clean shutdown is not implemented (stop ctx, etc.)
32 */ 32 */
@@ -385,7 +385,10 @@ run (void *cls,
385 fi, 385 fi,
386 namespace, 386 namespace,
387 this_id, 387 this_id,
388 next_id); 388 next_id,
389 (do_simulate)
390 ? GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY
391 : GNUNET_FS_PUBLISH_OPTION_NONE);
389} 392}
390 393
391 394