working on unindex
[oweals/gnunet.git] / src / fs / fs.h
1 /*
2      This file is part of GNUnet.
3      (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
4
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
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file fs/fs.h
23  * @brief definitions for the entire fs module
24  * @author Igor Wronsky, Christian Grothoff
25  */
26 #ifndef FS_H
27 #define FS_H
28
29 #include "gnunet_datastore_service.h"
30 #include "gnunet_fs_service.h"
31
32 /**
33  * Size of the individual blocks used for file-sharing.
34  */
35 #define DBLOCK_SIZE (32*1024)
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 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 MAX_INLINE_SIZE 65536
53
54
55 /**
56  * Blocksize to use when hashing files
57  * for indexing (blocksize for IO, not for
58  * the DBlocks).  Larger blocksizes can
59  * be more efficient but will be more disruptive
60  * as far as the scheduler is concerned.
61  */
62 #define HASHING_BLOCKSIZE (1024 * 1024)
63
64
65 /**
66  * @brief content hash key
67  */
68 struct ContentHashKey 
69 {
70   GNUNET_HashCode key;
71   GNUNET_HashCode query;
72 };
73
74
75 /**
76  * @brief complete information needed
77  * to download a file.
78  */
79 struct FileIdentifier
80 {
81
82   /**
83    * Total size of the file in bytes. (network byte order (!))
84    */
85   uint64_t file_length;
86
87   /**
88    * Query and key of the top GNUNET_EC_IBlock.
89    */
90   struct ContentHashKey chk;
91
92 };
93
94
95 /**
96  * Information about a file and its location
97  * (peer claiming to share the file).
98  */
99 struct Location
100 {
101   /**
102    * Information about the shared file.
103    */
104   struct FileIdentifier fi;
105
106   /**
107    * Identity of the peer sharing the file.
108    */
109   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded peer;
110
111   /**
112    * Time when this location URI expires.
113    */
114   struct GNUNET_TIME_Absolute expirationTime;
115
116   /**
117    * RSA signature over the GNUNET_EC_FileIdentifier,
118    * GNUNET_hash of the peer and expiration time.
119    */
120   struct GNUNET_CRYPTO_RsaSignature contentSignature;
121
122 };
123
124 enum uri_types
125 { chk, sks, ksk, loc };
126
127 /**
128  * A Universal Resource Identifier (URI), opaque.
129  */
130 struct GNUNET_FS_Uri
131 {
132   enum uri_types type;
133   union
134   {
135     struct
136     {
137       /**
138        * Keywords start with a '+' if they are
139        * mandatory (in which case the '+' is NOT
140        * part of the keyword) and with a
141        * simple space if they are optional
142        * (in which case the space is ALSO not
143        * part of the actual keyword).
144        *
145        * Double-quotes to protect spaces and
146        * %-encoding are NOT used internally
147        * (only in URI-strings).
148        */
149       char **keywords;
150       
151       /**
152        * Size of the keywords array.
153        */
154       unsigned int keywordCount;
155     } ksk;
156
157     struct
158     {
159       /**
160        * Hash of the public key for the namespace.
161        */
162       GNUNET_HashCode namespace;
163
164       /**
165        * Human-readable identifier chosen for this
166        * entry in the namespace.
167        */
168       char *identifier;
169     } sks;
170
171     /**
172      * Information needed to retrieve a file (content-hash-key
173      * plus file size).
174      */
175     struct FileIdentifier chk;
176
177     /**
178      * Information needed to retrieve a file including signed
179      * location (identity of a peer) of the content.
180      */
181     struct Location loc;
182   } data;
183
184 };
185
186
187 /**
188  * Information for a file or directory that is
189  * about to be published.
190  */
191 struct GNUNET_FS_FileInformation
192 {
193
194   /**
195    * Files in a directory are kept as a linked list.
196    */
197   struct GNUNET_FS_FileInformation *next;
198
199   /**
200    * If this is a file in a directory, "dir" refers to
201    * the directory; otherwise NULL.
202    */
203   struct GNUNET_FS_FileInformation *dir;
204
205   /**
206    * Pointer kept for the client.
207    */
208   void *client_info;
209
210   /**
211    * Metadata to use for the file.
212    */
213   struct GNUNET_CONTAINER_MetaData *meta;
214
215   /**
216    * Keywords to use for KBlocks.
217    */
218   struct GNUNET_FS_Uri *keywords;
219
220   /**
221    * CHK for this file or directory. NULL if
222    * we have not yet computed it.
223    */
224   struct GNUNET_FS_Uri *chk_uri;
225
226   /**
227    * At what time should the content expire?
228    */
229   struct GNUNET_TIME_Absolute expirationTime;
230
231   /**
232    * At what time did we start this upload?
233    */
234   struct GNUNET_TIME_Absolute start_time;
235
236   /**
237    * Under what filename is this struct serialized
238    * (for operational persistence).
239    */
240   char *serialization;
241
242   /**
243    * In-memory cache of the current CHK tree.
244    * This struct will contain the CHK values
245    * from the root to the currently processed
246    * node in the tree as identified by 
247    * "current_depth" and "publish_offset".
248    * The "chktree" will be initially NULL,
249    * then allocated to a sufficient number of
250    * entries for the size of the file and
251    * finally freed once the upload is complete.
252    */
253   struct ContentHashKey *chk_tree;
254
255   /**
256    * Error message (non-NULL if this operation
257    * failed).
258    */
259   char *emsg;
260   
261   /**
262    * Number of entries in "chk_tree".
263    */
264   unsigned int chk_tree_depth;
265
266   /**
267    * Depth in the CHK-tree at which we are
268    * currently publishing.  0 is the root
269    * of the tree.
270    */
271   unsigned int current_depth;
272
273   /**
274    * How many bytes of this file or directory have been
275    * published so far?
276    */
277   uint64_t publish_offset;
278
279   /**
280    * Data describing either the file or the directory.
281    */
282   union
283   {
284
285     /**
286      * Data for a file.
287      */
288     struct {
289
290       /**
291        * Function that can be used to read the data for the file.
292        */
293       GNUNET_FS_DataReader reader;
294
295       /**
296        * Closure for reader.
297        */
298       void *reader_cls;
299
300       /**
301        * Name of the file (must be an absolute path).
302        * Only required for indexing.  FIXME: not yet
303        * initialized!
304        */
305       char *filename;
306
307       /**
308        * If this file is being indexed, this value
309        * is set to the hash over the entire file
310        * (when the indexing process is started). 
311        * Otherwise this field is not used.
312        */
313       GNUNET_HashCode file_id;
314
315       /**
316        * Size of the file (in bytes).
317        */
318       uint64_t file_size;
319
320       /**
321        * Should the file be indexed or inserted?
322        */
323       int do_index;
324
325     } file;
326
327     /**
328      * Data for a directory.
329      */
330     struct {
331       
332       /**
333        * Name of the directory.
334        */
335       char *dirname;
336       
337       /**
338        * Linked list of entries in the directory.
339        */
340       struct GNUNET_FS_FileInformation *entries;
341
342       /**
343        * Size of the directory itself (in bytes); 0 if the
344        * size has not yet been calculated.
345        */
346       size_t dir_size;
347
348       /**
349        * Pointer to the data for the directory (or NULL if not
350        * available).
351        */
352       void *dir_data;
353
354     } dir;
355
356   } data;
357
358   /**
359    * Is this struct for a file or directory?
360    */
361   int is_directory;
362
363   /**
364    * Desired anonymity level.
365    */
366   unsigned int anonymity;
367
368   /**
369    * Desired priority (for keeping the content in the DB).
370    */
371   unsigned int priority;
372
373 };
374
375
376 /**
377  * Master context for most FS operations.
378  */
379 struct GNUNET_FS_Handle
380 {
381   /**
382    * Scheduler.
383    */
384   struct GNUNET_SCHEDULER_Handle *sched;
385
386   /**
387    * Configuration to use.
388    */
389   const struct GNUNET_CONFIGURATION_Handle *cfg;
390
391   /**
392    * Name of our client.
393    */
394   char *client_name;
395
396   /**
397    * Function to call with updates on our progress.
398    */
399   GNUNET_FS_ProgressCallback upcb;
400
401   /**
402    * Closure for upcb.
403    */
404   void *upcb_cls;
405
406   /**
407    * Connection to the FS service.
408    */
409   struct GNUNET_CLIENT_Connection *client;
410
411
412 };
413
414
415 /**
416  * Handle for controlling an upload.
417  */
418 struct GNUNET_FS_PublishContext
419 {
420   /**
421    * Handle to the global fs context.
422    */ 
423   struct GNUNET_FS_Handle *h;
424
425   /**
426    * Argument to pass to the client in callbacks.
427    */
428   void *client_ctx;
429   
430   /**
431    * File-structure that is being shared.
432    */
433   struct GNUNET_FS_FileInformation *fi;
434
435   /**
436    * Namespace that we are publishing in, NULL if we have no namespace.
437    */
438   struct GNUNET_FS_Namespace *namespace;
439
440   /**
441    * ID of the content in the namespace, NULL if we have no namespace.
442    */
443   char *nid;
444
445   /**
446    * ID for future updates, NULL if we have no namespace or no updates.
447    */
448   char *nuid;
449
450   /**
451    * ID of the task performing the upload. NO_TASK
452    * if the upload has completed.
453    */
454   GNUNET_SCHEDULER_TaskIdentifier upload_task;
455
456   /**
457    * Our own client handle for the FS service;
458    * only briefly used when we start to index a
459    * file, otherwise NULL.
460    */
461   struct GNUNET_CLIENT_Connection *client;
462
463   /**
464    * Typically GNUNET_NO.  Set to GNUNET_YES if
465    * "upload_task" is GNUNET_SCHEDULER_NO_TASK
466    * and we're waiting for a response from the
467    * datastore service (in which case this
468    * struct must not be freed until we have that
469    * response).  If someone tries to stop the
470    * download for good during this period, 
471    * "in_network_wait" is set to GNUNET_SYSERR
472    * which will cause the struct to be destroyed
473    * right after we have the reply (or timeout)
474    * from the datastore service.
475    */
476   int in_network_wait;
477
478   /**
479    * Options for publishing.
480    */
481   enum GNUNET_FS_PublishOptions options;
482
483   /**
484    * Current position in the file-tree for the
485    * upload.
486    */
487   struct GNUNET_FS_FileInformation *fi_pos;
488
489   /**
490    * Connection to the datastore service.
491    */
492   struct GNUNET_DATASTORE_Handle *dsh;
493
494   /**
495    * Space reservation ID with datastore service
496    * for this upload.
497    */
498   int rid;
499 };
500
501
502 /**
503  * Phases of unindex processing (state machine).
504  */ 
505 enum UnindexState
506   {
507     /**
508      * We're currently hashing the file.
509      */
510     UNINDEX_STATE_HASHING = 0,
511
512     /**
513      * We're notifying the FS service about
514      * the unindexing.
515      */
516     UNINDEX_STATE_FS_NOTIFY = 1,
517
518     /**
519      * We're telling the datastore to delete
520      * the respective entries.
521      */
522     UNINDEX_STATE_DS_REMOVE = 2,
523
524     /**
525      * We're done.
526      */
527     UNINDEX_STATE_COMPLETE = 3,
528
529     /**
530      * We've encountered a fatal error.
531      */
532     UNINDEX_STATE_ERROR = 4,
533
534     /**
535      * We've been aborted.  The next callback should clean up the
536      * struct.
537      */
538     UNINDEX_STATE_ABORTED = 5
539   };
540
541
542 /**
543  * Handle for controlling an unindexing operation.
544  */
545 struct GNUNET_FS_UnindexContext
546 {
547   
548   /**
549    * Global FS context.
550    */
551   struct GNUNET_FS_Handle *h;
552
553   /**
554    * Name of the file that we are unindexing.
555    */
556   char *filename;
557
558   /**
559    * Connection to the FS service,
560    * only valid during the UNINDEX_STATE_FS_NOTIFY
561    * phase.
562    */
563   struct GNUNET_CLIENT_Connection *client;
564
565   /**
566    * Connection to the datastore service,
567    * only valid during the UNINDEX_STATE_DS_NOTIFY
568    * phase.
569    */
570   struct GNUNET_DATASTORE_Handle *dsh;
571
572   /**
573    * Pointer kept for the client.
574    */
575   void *client_info;
576
577   /**
578    * Overall size of the file.
579    */ 
580   uint64_t file_size;
581
582   /**
583    * How far have we gotten?
584    */ 
585   uint64_t unindex_offset;
586
587   /**
588    * When did we start?
589    */
590   struct GNUNET_TIME_Absolute start_time;
591
592   /**
593    * Hash of the file's contents (once
594    * computed).
595    */
596   GNUNET_HashCode file_id;
597  
598   /**
599    * Current operatinonal phase.
600    */
601   enum UnindexState state; 
602
603 };
604
605
606 /**
607  * Handle for controlling a search.
608  */
609 struct GNUNET_FS_SearchContext
610 {
611 };
612
613
614 /**
615  * Context for controlling a download.
616  */
617 struct GNUNET_FS_DownloadContext
618 {
619 };
620
621 struct GNUNET_FS_Namespace
622 {
623
624   /**
625    * Private key for the namespace.
626    */
627   struct GNUNET_CRYPTO_RsaPrivateKey *key;
628
629   /**
630    * Reference counter.
631    */
632   unsigned int rc;
633 };
634
635
636 /**
637  * @brief index block (indexing a DBlock that 
638  *        can be obtained directly from reading
639  *        the plaintext file)
640  */
641 struct OnDemandBlock
642 {
643   /**
644    * Hash code of the entire content of the
645    * file that was indexed (used to uniquely
646    * identify the plaintext file).
647    */
648   GNUNET_HashCode file_id;
649
650   /**
651    * At which offset should we be able to find
652    * this on-demand encoded block?
653    */
654   uint64_t offset;
655
656 };
657
658
659 /**
660  * @brief keyword block (advertising data under a keyword)
661  */
662 struct KBlock
663 {
664
665   /**
666    * GNUNET_RSA_Signature using RSA-key generated from search keyword.
667    */
668   struct GNUNET_CRYPTO_RsaSignature signature;
669
670   /**
671    * What is being signed and why?
672    */
673   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
674
675   /**
676    * Key generated (!) from the H(keyword) as the seed!
677    */
678   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded keyspace;
679
680   /* 0-terminated URI here */
681
682   /* variable-size Meta-Data follows here */
683
684 };
685
686 /**
687  * @brief namespace content block (advertising data under an identifier in a namespace)
688  */
689 struct SBlock
690 {
691
692   /**
693    * GNUNET_RSA_Signature using RSA-key of the namespace
694    */
695   struct GNUNET_CRYPTO_RsaSignature signature;
696
697   /**
698    * What is being signed and why?
699    */
700   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
701
702   /**
703    * Hash of the hash of the human-readable identifier used for
704    * this entry (the hash of the human-readable identifier is
705    * used as the key for decryption; the xor of this identifier
706    * and the hash of the "keyspace" is the datastore-query hash).
707    */
708   GNUNET_HashCode identifier;
709
710   /**
711    * Public key of the namespace.
712    */
713   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded subspace;
714
715   /* 0-terminated update-identifier here */
716
717   /* 0-terminated URI here */
718
719   /* variable-size Meta-Data follows here */
720
721 };
722
723
724 /**
725  * Message sent from a GNUnet (fs) publishing
726  * activity to the gnunet-fs-service to 
727  * initiate indexing of a file.  The service
728  * is supposed to check if the specified file
729  * is available and has the same cryptographic
730  * hash.  It should then respond with either
731  * a confirmation or a denial.
732  *
733  * On OSes where this works, it is considered
734  * acceptable if the service only checks that
735  * the path, device and inode match (it can
736  * then be assumed that the hash will also match
737  * without actually computing it; this is an
738  * optimization that should be safe given that
739  * the client is not our adversary).
740  */
741 struct IndexStartMessage
742 {
743
744   /**
745    * Message type will be 
746    * GNUNET_MESSAGE_TYPE_FS_INDEX_START.
747    */
748   struct GNUNET_MessageHeader header;
749
750   /**
751    * ID of device containing the file, as seen by the client.  This
752    * device ID is obtained using a call like "statvfs" (and converting
753    * the "f_fsid" field to a 32-bit big-endian number).  Use 0 if the
754    * OS does not support this, in which case the service must do a
755    * full hash recomputation.
756    */
757   uint32_t device;
758   
759   /**
760    * Inode of the file on the given device, as seen by the client
761    * ("st_ino" field from "struct stat").  Use 0 if the OS does not
762    * support this, in which case the service must do a full hash
763    * recomputation.
764    */
765   uint64_t inode;
766
767   /**
768    * Hash of the file that we would like to index.
769    */
770   GNUNET_HashCode file_id;
771
772   /* this is followed by a 0-terminated
773      filename of a file with the hash
774      "file_id" as seen by the client */
775
776 };
777
778
779 /**
780  * Message send by FS service in response to a request
781  * asking for a list of all indexed files.
782  */
783 struct IndexInfoMessage
784 {
785   /**
786    * Message type will be 
787    * GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY.
788    */
789   struct GNUNET_MessageHeader header;
790
791   /**
792    * Hash of the indexed file.
793    */
794   GNUNET_HashCode file_id;
795
796   /* this is followed by a 0-terminated
797      filename of a file with the hash
798      "file_id" as seen by the client */
799   
800 };
801
802
803 /**
804  * Message sent from a GNUnet (fs) unindexing
805  * activity to the gnunet-fs-service to 
806  * indicate that a file will be unindexed.  The service
807  * is supposed to remove the file from the
808  * list of indexed files and response with
809  * a confirmation message (even if the file
810  * was already not on the list).
811  */
812 struct UnindexMessage
813 {
814
815   /**
816    * Message type will be 
817    * GNUNET_MESSAGE_TYPE_FS_UNINDEX.
818    */
819   struct GNUNET_MessageHeader header;
820
821   /**
822    * Always zero.
823    */
824   uint32_t reserved;
825
826   /**
827    * Hash of the file that we will unindex.
828    */
829   GNUNET_HashCode file_id;
830
831 };
832
833
834
835 #endif
836
837 /* end of fs.h */