refactoring publishing code
[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    * Encoder being used to publish this file.
257    */
258   struct GNUNET_FS_TreeEncoder *te;
259
260   /**
261    * Error message (non-NULL if this operation
262    * failed).
263    */
264   char *emsg;
265   
266   /**
267    * Number of entries in "chk_tree".
268    */
269   // unsigned int chk_tree_depth;
270
271   /**
272    * Depth in the CHK-tree at which we are
273    * currently publishing.  0 is the root
274    * of the tree.
275    */
276   // unsigned int current_depth;
277
278   /**
279    * How many bytes of this file or directory have been
280    * published so far?
281    */
282   // uint64_t publish_offset;
283
284   /**
285    * Data describing either the file or the directory.
286    */
287   union
288   {
289
290     /**
291      * Data for a file.
292      */
293     struct {
294
295       /**
296        * Function that can be used to read the data for the file.
297        */
298       GNUNET_FS_DataReader reader;
299
300       /**
301        * Closure for reader.
302        */
303       void *reader_cls;
304
305       /**
306        * Name of the file (must be an absolute path).
307        * Only required for indexing.  FIXME: not yet
308        * initialized!
309        */
310       char *filename;
311
312       /**
313        * If this file is being indexed, this value
314        * is set to the hash over the entire file
315        * (when the indexing process is started). 
316        * Otherwise this field is not used.
317        */
318       GNUNET_HashCode file_id;
319
320       /**
321        * Size of the file (in bytes).
322        */
323       uint64_t file_size;
324
325       /**
326        * Should the file be indexed or inserted?
327        */
328       int do_index;
329
330     } file;
331
332     /**
333      * Data for a directory.
334      */
335     struct {
336       
337       /**
338        * Name of the directory.
339        */
340       char *dirname;
341       
342       /**
343        * Linked list of entries in the directory.
344        */
345       struct GNUNET_FS_FileInformation *entries;
346
347       /**
348        * Size of the directory itself (in bytes); 0 if the
349        * size has not yet been calculated.
350        */
351       size_t dir_size;
352
353       /**
354        * Pointer to the data for the directory (or NULL if not
355        * available).
356        */
357       void *dir_data;
358
359     } dir;
360
361   } data;
362
363   /**
364    * Is this struct for a file or directory?
365    */
366   int is_directory;
367
368   /**
369    * Desired anonymity level.
370    */
371   unsigned int anonymity;
372
373   /**
374    * Desired priority (for keeping the content in the DB).
375    */
376   unsigned int priority;
377
378 };
379
380
381 /**
382  * Master context for most FS operations.
383  */
384 struct GNUNET_FS_Handle
385 {
386   /**
387    * Scheduler.
388    */
389   struct GNUNET_SCHEDULER_Handle *sched;
390
391   /**
392    * Configuration to use.
393    */
394   const struct GNUNET_CONFIGURATION_Handle *cfg;
395
396   /**
397    * Name of our client.
398    */
399   char *client_name;
400
401   /**
402    * Function to call with updates on our progress.
403    */
404   GNUNET_FS_ProgressCallback upcb;
405
406   /**
407    * Closure for upcb.
408    */
409   void *upcb_cls;
410
411   /**
412    * Connection to the FS service.
413    */
414   struct GNUNET_CLIENT_Connection *client;
415
416
417 };
418
419
420 /**
421  * Handle for controlling an upload.
422  */
423 struct GNUNET_FS_PublishContext
424 {
425   /**
426    * Handle to the global fs context.
427    */ 
428   struct GNUNET_FS_Handle *h;
429
430   /**
431    * Argument to pass to the client in callbacks.
432    */
433   void *client_ctx;
434   
435   /**
436    * File-structure that is being shared.
437    */
438   struct GNUNET_FS_FileInformation *fi;
439
440   /**
441    * Namespace that we are publishing in, NULL if we have no namespace.
442    */
443   struct GNUNET_FS_Namespace *namespace;
444
445   /**
446    * ID of the content in the namespace, NULL if we have no namespace.
447    */
448   char *nid;
449
450   /**
451    * ID for future updates, NULL if we have no namespace or no updates.
452    */
453   char *nuid;
454
455   /**
456    * ID of the task performing the upload. NO_TASK
457    * if the upload has completed.
458    */
459   GNUNET_SCHEDULER_TaskIdentifier upload_task;
460
461   /**
462    * Our own client handle for the FS service;
463    * only briefly used when we start to index a
464    * file, otherwise NULL.
465    */
466   struct GNUNET_CLIENT_Connection *client;
467
468   /**
469    * Typically GNUNET_NO.  Set to GNUNET_YES if
470    * "upload_task" is GNUNET_SCHEDULER_NO_TASK
471    * and we're waiting for a response from the
472    * datastore service (in which case this
473    * struct must not be freed until we have that
474    * response).  If someone tries to stop the
475    * download for good during this period, 
476    * "in_network_wait" is set to GNUNET_SYSERR
477    * which will cause the struct to be destroyed
478    * right after we have the reply (or timeout)
479    * from the datastore service.
480    */
481   int in_network_wait;
482
483   /**
484    * Options for publishing.
485    */
486   enum GNUNET_FS_PublishOptions options;
487
488   /**
489    * Current position in the file-tree for the
490    * upload.
491    */
492   struct GNUNET_FS_FileInformation *fi_pos;
493
494   /**
495    * Connection to the datastore service.
496    */
497   struct GNUNET_DATASTORE_Handle *dsh;
498
499   /**
500    * Space reservation ID with datastore service
501    * for this upload.
502    */
503   int rid;
504 };
505
506
507 /**
508  * Phases of unindex processing (state machine).
509  */ 
510 enum UnindexState
511   {
512     /**
513      * We're currently hashing the file.
514      */
515     UNINDEX_STATE_HASHING = 0,
516
517     /**
518      * We're notifying the FS service about
519      * the unindexing.
520      */
521     UNINDEX_STATE_FS_NOTIFY = 1,
522
523     /**
524      * We're telling the datastore to delete
525      * the respective entries.
526      */
527     UNINDEX_STATE_DS_REMOVE = 2,
528
529     /**
530      * We're done.
531      */
532     UNINDEX_STATE_COMPLETE = 3,
533
534     /**
535      * We've encountered a fatal error.
536      */
537     UNINDEX_STATE_ERROR = 4,
538
539     /**
540      * We've been aborted.  The next callback should clean up the
541      * struct.
542      */
543     UNINDEX_STATE_ABORTED = 5
544   };
545
546
547 /**
548  * Handle for controlling an unindexing operation.
549  */
550 struct GNUNET_FS_UnindexContext
551 {
552   
553   /**
554    * Global FS context.
555    */
556   struct GNUNET_FS_Handle *h;
557
558   /**
559    * Name of the file that we are unindexing.
560    */
561   char *filename;
562
563   /**
564    * Connection to the FS service,
565    * only valid during the UNINDEX_STATE_FS_NOTIFY
566    * phase.
567    */
568   struct GNUNET_CLIENT_Connection *client;
569
570   /**
571    * Connection to the datastore service,
572    * only valid during the UNINDEX_STATE_DS_NOTIFY
573    * phase.
574    */
575   struct GNUNET_DATASTORE_Handle *dsh;
576
577   /**
578    * Pointer kept for the client.
579    */
580   void *client_info;
581
582   /**
583    * Overall size of the file.
584    */ 
585   uint64_t file_size;
586
587   /**
588    * How far have we gotten?
589    */ 
590   uint64_t unindex_offset;
591
592   /**
593    * When did we start?
594    */
595   struct GNUNET_TIME_Absolute start_time;
596
597   /**
598    * Hash of the file's contents (once
599    * computed).
600    */
601   GNUNET_HashCode file_id;
602  
603   /**
604    * Current operatinonal phase.
605    */
606   enum UnindexState state; 
607
608 };
609
610
611 /**
612  * Handle for controlling a search.
613  */
614 struct GNUNET_FS_SearchContext
615 {
616 };
617
618
619 /**
620  * Context for controlling a download.
621  */
622 struct GNUNET_FS_DownloadContext
623 {
624 };
625
626 struct GNUNET_FS_Namespace
627 {
628
629   /**
630    * Private key for the namespace.
631    */
632   struct GNUNET_CRYPTO_RsaPrivateKey *key;
633
634   /**
635    * Reference counter.
636    */
637   unsigned int rc;
638 };
639
640
641 /**
642  * @brief index block (indexing a DBlock that 
643  *        can be obtained directly from reading
644  *        the plaintext file)
645  */
646 struct OnDemandBlock
647 {
648   /**
649    * Hash code of the entire content of the
650    * file that was indexed (used to uniquely
651    * identify the plaintext file).
652    */
653   GNUNET_HashCode file_id;
654
655   /**
656    * At which offset should we be able to find
657    * this on-demand encoded block?
658    */
659   uint64_t offset;
660
661 };
662
663
664 /**
665  * @brief keyword block (advertising data under a keyword)
666  */
667 struct KBlock
668 {
669
670   /**
671    * GNUNET_RSA_Signature using RSA-key generated from search keyword.
672    */
673   struct GNUNET_CRYPTO_RsaSignature signature;
674
675   /**
676    * What is being signed and why?
677    */
678   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
679
680   /**
681    * Key generated (!) from the H(keyword) as the seed!
682    */
683   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded keyspace;
684
685   /* 0-terminated URI here */
686
687   /* variable-size Meta-Data follows here */
688
689 };
690
691 /**
692  * @brief namespace content block (advertising data under an identifier in a namespace)
693  */
694 struct SBlock
695 {
696
697   /**
698    * GNUNET_RSA_Signature using RSA-key of the namespace
699    */
700   struct GNUNET_CRYPTO_RsaSignature signature;
701
702   /**
703    * What is being signed and why?
704    */
705   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
706
707   /**
708    * Hash of the hash of the human-readable identifier used for
709    * this entry (the hash of the human-readable identifier is
710    * used as the key for decryption; the xor of this identifier
711    * and the hash of the "keyspace" is the datastore-query hash).
712    */
713   GNUNET_HashCode identifier;
714
715   /**
716    * Public key of the namespace.
717    */
718   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded subspace;
719
720   /* 0-terminated update-identifier here */
721
722   /* 0-terminated URI here */
723
724   /* variable-size Meta-Data follows here */
725
726 };
727
728
729 /**
730  * Message sent from a GNUnet (fs) publishing
731  * activity to the gnunet-fs-service to 
732  * initiate indexing of a file.  The service
733  * is supposed to check if the specified file
734  * is available and has the same cryptographic
735  * hash.  It should then respond with either
736  * a confirmation or a denial.
737  *
738  * On OSes where this works, it is considered
739  * acceptable if the service only checks that
740  * the path, device and inode match (it can
741  * then be assumed that the hash will also match
742  * without actually computing it; this is an
743  * optimization that should be safe given that
744  * the client is not our adversary).
745  */
746 struct IndexStartMessage
747 {
748
749   /**
750    * Message type will be 
751    * GNUNET_MESSAGE_TYPE_FS_INDEX_START.
752    */
753   struct GNUNET_MessageHeader header;
754
755   /**
756    * ID of device containing the file, as seen by the client.  This
757    * device ID is obtained using a call like "statvfs" (and converting
758    * the "f_fsid" field to a 32-bit big-endian number).  Use 0 if the
759    * OS does not support this, in which case the service must do a
760    * full hash recomputation.
761    */
762   uint32_t device;
763   
764   /**
765    * Inode of the file on the given device, as seen by the client
766    * ("st_ino" field from "struct stat").  Use 0 if the OS does not
767    * support this, in which case the service must do a full hash
768    * recomputation.
769    */
770   uint64_t inode;
771
772   /**
773    * Hash of the file that we would like to index.
774    */
775   GNUNET_HashCode file_id;
776
777   /* this is followed by a 0-terminated
778      filename of a file with the hash
779      "file_id" as seen by the client */
780
781 };
782
783
784 /**
785  * Message send by FS service in response to a request
786  * asking for a list of all indexed files.
787  */
788 struct IndexInfoMessage
789 {
790   /**
791    * Message type will be 
792    * GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY.
793    */
794   struct GNUNET_MessageHeader header;
795
796   /**
797    * Hash of the indexed file.
798    */
799   GNUNET_HashCode file_id;
800
801   /* this is followed by a 0-terminated
802      filename of a file with the hash
803      "file_id" as seen by the client */
804   
805 };
806
807
808 /**
809  * Message sent from a GNUnet (fs) unindexing
810  * activity to the gnunet-fs-service to 
811  * indicate that a file will be unindexed.  The service
812  * is supposed to remove the file from the
813  * list of indexed files and response with
814  * a confirmation message (even if the file
815  * was already not on the list).
816  */
817 struct UnindexMessage
818 {
819
820   /**
821    * Message type will be 
822    * GNUNET_MESSAGE_TYPE_FS_UNINDEX.
823    */
824   struct GNUNET_MessageHeader header;
825
826   /**
827    * Always zero.
828    */
829   uint32_t reserved;
830
831   /**
832    * Hash of the file that we will unindex.
833    */
834   GNUNET_HashCode file_id;
835
836 };
837
838
839
840 #endif
841
842 /* end of fs.h */