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