hacking on fs
[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_constants.h"
30 #include "gnunet_datastore_service.h"
31 #include "gnunet_fs_service.h"
32
33 /**
34  * Size of the individual blocks used for file-sharing.
35  */
36 #define DBLOCK_SIZE (32*1024)
37
38
39 /**
40  * Pick a multiple of 2 here to achive 8-byte alignment!
41  * We also probably want DBlocks to have (roughly) the
42  * same size as IBlocks.  With SHA-512, the optimal
43  * value is 32768 byte / 128 byte = 256
44  * (128 byte = 2 * 512 bits).  DO NOT CHANGE!
45  */
46 #define CHK_PER_INODE 256
47
48
49 /**
50  * Maximum size for a file to be considered for
51  * inlining in a directory.
52  */
53 #define MAX_INLINE_SIZE 65536
54
55
56 /**
57  * Blocksize to use when hashing files
58  * for indexing (blocksize for IO, not for
59  * the DBlocks).  Larger blocksizes can
60  * be more efficient but will be more disruptive
61  * as far as the scheduler is concerned.
62  */
63 #define HASHING_BLOCKSIZE (1024 * 1024)
64
65 /**
66  * Number of bits we set per entry in the bloomfilter.
67  * Do not change!
68  */
69 #define BLOOMFILTER_K 16
70
71 /**
72  * By how much (in ms) do we decrement the TTL
73  * at each hop?
74  */
75 #define TTL_DECREMENT 5000
76
77 /**
78  * Length of the P2P success tracker.  Note that
79  * having a very long list can also hurt performance.
80  */
81 #define P2P_SUCCESS_LIST_SIZE 8
82
83
84 /**
85  * Length of the CS-2-P success tracker.  Note that
86  * having a very long list can also hurt performance.
87  */
88 #define CS2P_SUCCESS_LIST_SIZE 8
89
90 /**
91  * How long are we willing to wait for the datastore to be ready to
92  * process a request for a query without priority?
93  */
94 #define BASIC_DATASTORE_REQUEST_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
95
96
97 /**
98  * How long are we willing to wait for the core to be ready to
99  * transmit a reply to the target peer (if we can not transmit
100  * until then, we will discard the reply).
101  */
102 #define ACCEPTABLE_REPLY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
103
104
105 /**
106  * Bandwidth value of an (effectively) 0-priority query.
107  */
108 #define QUERY_BANDWIDTH_VALUE 0.001
109
110 /**
111  * Bandwidth value of a 0-priority content (must be
112  * fairly high compared to query since content is
113  * typically significantly larger -- and more valueable
114  * since it can take many queries to get one piece of
115  * content).
116  */
117 #define CONTENT_BANDWIDTH_VALUE 0.8
118
119 /**
120  * By which amount do we decrement the TTL for simple forwarding /
121  * indirection of the query; in milli-seconds.  Set somewhat in
122  * accordance to your network latency (above the time it'll take you
123  * to send a packet and get a reply).
124  */
125 #define TTL_DECREMENT 5000
126
127 /**
128  * Until which load do we consider the peer idle and do not
129  * charge at all? (should be larger than GNUNET_IDLE_LOAD_THRESHOLD used
130  * by the rest of the code)!
131  */
132 #define IDLE_LOAD_THRESHOLD ((100 + GNUNET_CONSTANTS_IDLE_LOAD_THRESHOLD) / 2)
133
134
135
136 /**
137  * @brief content hash key
138  */
139 struct ContentHashKey 
140 {
141   GNUNET_HashCode key;
142   GNUNET_HashCode query;
143 };
144
145
146 /**
147  * @brief complete information needed
148  * to download a file.
149  */
150 struct FileIdentifier
151 {
152
153   /**
154    * Total size of the file in bytes. (network byte order (!))
155    */
156   uint64_t file_length;
157
158   /**
159    * Query and key of the top GNUNET_EC_IBlock.
160    */
161   struct ContentHashKey chk;
162
163 };
164
165
166 /**
167  * Information about a file and its location
168  * (peer claiming to share the file).
169  */
170 struct Location
171 {
172   /**
173    * Information about the shared file.
174    */
175   struct FileIdentifier fi;
176
177   /**
178    * Identity of the peer sharing the file.
179    */
180   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded peer;
181
182   /**
183    * Time when this location URI expires.
184    */
185   struct GNUNET_TIME_Absolute expirationTime;
186
187   /**
188    * RSA signature over the GNUNET_EC_FileIdentifier,
189    * GNUNET_hash of the peer and expiration time.
190    */
191   struct GNUNET_CRYPTO_RsaSignature contentSignature;
192
193 };
194
195 enum uri_types
196 { chk, sks, ksk, loc };
197
198 /**
199  * A Universal Resource Identifier (URI), opaque.
200  */
201 struct GNUNET_FS_Uri
202 {
203   enum uri_types type;
204   union
205   {
206     struct
207     {
208       /**
209        * Keywords start with a '+' if they are
210        * mandatory (in which case the '+' is NOT
211        * part of the keyword) and with a
212        * simple space if they are optional
213        * (in which case the space is ALSO not
214        * part of the actual keyword).
215        *
216        * Double-quotes to protect spaces and
217        * %-encoding are NOT used internally
218        * (only in URI-strings).
219        */
220       char **keywords;
221       
222       /**
223        * Size of the keywords array.
224        */
225       unsigned int keywordCount;
226     } ksk;
227
228     struct
229     {
230       /**
231        * Hash of the public key for the namespace.
232        */
233       GNUNET_HashCode namespace;
234
235       /**
236        * Human-readable identifier chosen for this
237        * entry in the namespace.
238        */
239       char *identifier;
240     } sks;
241
242     /**
243      * Information needed to retrieve a file (content-hash-key
244      * plus file size).
245      */
246     struct FileIdentifier chk;
247
248     /**
249      * Information needed to retrieve a file including signed
250      * location (identity of a peer) of the content.
251      */
252     struct Location loc;
253   } data;
254
255 };
256
257
258 /**
259  * Information for a file or directory that is
260  * about to be published.
261  */
262 struct GNUNET_FS_FileInformation
263 {
264
265   /**
266    * Files in a directory are kept as a linked list.
267    */
268   struct GNUNET_FS_FileInformation *next;
269
270   /**
271    * If this is a file in a directory, "dir" refers to
272    * the directory; otherwise NULL.
273    */
274   struct GNUNET_FS_FileInformation *dir;
275
276   /**
277    * Pointer kept for the client.
278    */
279   void *client_info;
280
281   /**
282    * Metadata to use for the file.
283    */
284   struct GNUNET_CONTAINER_MetaData *meta;
285
286   /**
287    * Keywords to use for KBlocks.
288    */
289   struct GNUNET_FS_Uri *keywords;
290
291   /**
292    * CHK for this file or directory. NULL if
293    * we have not yet computed it.
294    */
295   struct GNUNET_FS_Uri *chk_uri;
296
297   /**
298    * At what time should the content expire?
299    */
300   struct GNUNET_TIME_Absolute expirationTime;
301
302   /**
303    * At what time did we start this upload?
304    */
305   struct GNUNET_TIME_Absolute start_time;
306
307   /**
308    * Under what filename is this struct serialized
309    * (for operational persistence).
310    */
311   char *serialization;
312   
313   /**
314    * Encoder being used to publish this file.
315    */
316   struct GNUNET_FS_TreeEncoder *te;
317
318   /**
319    * Error message (non-NULL if this operation
320    * failed).
321    */
322   char *emsg;
323
324   /**
325    * Data describing either the file or the directory.
326    */
327   union
328   {
329
330     /**
331      * Data for a file.
332      */
333     struct {
334
335       /**
336        * Function that can be used to read the data for the file.
337        */
338       GNUNET_FS_DataReader reader;
339
340       /**
341        * Closure for reader.
342        */
343       void *reader_cls;
344
345       /**
346        * Name of the file (must be an absolute path).
347        * Only required for indexing.  FIXME: not yet
348        * initialized!
349        */
350       char *filename;
351
352       /**
353        * If this file is being indexed, this value
354        * is set to the hash over the entire file
355        * (when the indexing process is started). 
356        * Otherwise this field is not used.
357        */
358       GNUNET_HashCode file_id;
359
360       /**
361        * Size of the file (in bytes).
362        */
363       uint64_t file_size;
364
365       /**
366        * Should the file be indexed or inserted?
367        */
368       int do_index;
369
370     } file;
371
372     /**
373      * Data for a directory.
374      */
375     struct {
376       
377       /**
378        * Name of the directory.
379        */
380       char *dirname;
381       
382       /**
383        * Linked list of entries in the directory.
384        */
385       struct GNUNET_FS_FileInformation *entries;
386
387       /**
388        * Size of the directory itself (in bytes); 0 if the
389        * size has not yet been calculated.
390        */
391       size_t dir_size;
392
393       /**
394        * Pointer to the data for the directory (or NULL if not
395        * available).
396        */
397       void *dir_data;
398
399     } dir;
400
401   } data;
402
403   /**
404    * Is this struct for a file or directory?
405    */
406   int is_directory;
407
408   /**
409    * Desired anonymity level.
410    */
411   uint32_t anonymity;
412
413   /**
414    * Desired priority (for keeping the content in the DB).
415    */
416   uint32_t priority;
417
418 };
419
420
421 /**
422  * Master context for most FS operations.
423  */
424 struct GNUNET_FS_Handle
425 {
426   /**
427    * Scheduler.
428    */
429   struct GNUNET_SCHEDULER_Handle *sched;
430
431   /**
432    * Configuration to use.
433    */
434   const struct GNUNET_CONFIGURATION_Handle *cfg;
435
436   /**
437    * Name of our client.
438    */
439   char *client_name;
440
441   /**
442    * Function to call with updates on our progress.
443    */
444   GNUNET_FS_ProgressCallback upcb;
445
446   /**
447    * Closure for upcb.
448    */
449   void *upcb_cls;
450
451   /**
452    * Connection to the FS service.
453    */
454   struct GNUNET_CLIENT_Connection *client;
455
456   /**
457    * How many downloads probing availability
458    * of search results do we have running
459    * right now?
460    */
461   unsigned int active_probes;
462
463   /**
464    * General flags.
465    */
466   enum GNUNET_FS_Flags flags;
467
468 };
469
470
471 /**
472  * Handle for controlling an upload.
473  */
474 struct GNUNET_FS_PublishContext
475 {
476   /**
477    * Handle to the global fs context.
478    */ 
479   struct GNUNET_FS_Handle *h;
480
481   /**
482    * File-structure that is being shared.
483    */
484   struct GNUNET_FS_FileInformation *fi;
485
486   /**
487    * Namespace that we are publishing in, NULL if we have no namespace.
488    */
489   struct GNUNET_FS_Namespace *namespace;
490
491   /**
492    * ID of the content in the namespace, NULL if we have no namespace.
493    */
494   char *nid;
495
496   /**
497    * ID for future updates, NULL if we have no namespace or no updates.
498    */
499   char *nuid;
500
501   /**
502    * Our own client handle for the FS service;
503    * only briefly used when we start to index a
504    * file, otherwise NULL.
505    */
506   struct GNUNET_CLIENT_Connection *client;
507
508   /**
509    * Current position in the file-tree for the
510    * upload.
511    */
512   struct GNUNET_FS_FileInformation *fi_pos;
513
514   /**
515    * Connection to the datastore service.
516    */
517   struct GNUNET_DATASTORE_Handle *dsh;
518
519   /**
520    * ID of the task performing the upload. NO_TASK
521    * if the upload has completed.
522    */
523   GNUNET_SCHEDULER_TaskIdentifier upload_task;
524
525   /**
526    * Typically GNUNET_NO.  Set to GNUNET_YES if
527    * "upload_task" is GNUNET_SCHEDULER_NO_TASK
528    * and we're waiting for a response from the
529    * datastore service (in which case this
530    * struct must not be freed until we have that
531    * response).  If someone tries to stop the
532    * download for good during this period, 
533    * "in_network_wait" is set to GNUNET_SYSERR
534    * which will cause the struct to be destroyed
535    * right after we have the reply (or timeout)
536    * from the datastore service.
537    */
538   int in_network_wait;
539
540   /**
541    * Options for publishing.
542    */
543   enum GNUNET_FS_PublishOptions options;
544
545   /**
546    * Space reservation ID with datastore service
547    * for this upload.
548    */
549   int rid;
550
551   /**
552    * Set to GNUNET_YES if all processing has completed.
553    */
554   int all_done;
555 };
556
557
558 /**
559  * Phases of unindex processing (state machine).
560  */ 
561 enum UnindexState
562   {
563     /**
564      * We're currently hashing the file.
565      */
566     UNINDEX_STATE_HASHING = 0,
567
568     /**
569      * We're notifying the FS service about
570      * the unindexing.
571      */
572     UNINDEX_STATE_FS_NOTIFY = 1,
573
574     /**
575      * We're telling the datastore to delete
576      * the respective entries.
577      */
578     UNINDEX_STATE_DS_REMOVE = 2,
579
580     /**
581      * We're done.
582      */
583     UNINDEX_STATE_COMPLETE = 3,
584
585     /**
586      * We've encountered a fatal error.
587      */
588     UNINDEX_STATE_ERROR = 4,
589
590     /**
591      * We've been aborted.  The next callback should clean up the
592      * struct.
593      */
594     UNINDEX_STATE_ABORTED = 5
595   };
596
597
598 /**
599  * Handle for controlling an unindexing operation.
600  */
601 struct GNUNET_FS_UnindexContext
602 {
603   
604   /**
605    * Global FS context.
606    */
607   struct GNUNET_FS_Handle *h;
608
609   /**
610    * Name of the file that we are unindexing.
611    */
612   char *filename;
613
614   /**
615    * Connection to the FS service,
616    * only valid during the UNINDEX_STATE_FS_NOTIFY
617    * phase.
618    */
619   struct GNUNET_CLIENT_Connection *client;
620
621   /**
622    * Connection to the datastore service,
623    * only valid during the UNINDEX_STATE_DS_NOTIFY
624    * phase.
625    */
626   struct GNUNET_DATASTORE_Handle *dsh;
627
628   /**
629    * Pointer kept for the client.
630    */
631   void *client_info;
632
633   /**
634    * Merkle-ish tree encoder context.
635    */
636   struct GNUNET_FS_TreeEncoder *tc;
637
638   /**
639    * Handle used to read the file.
640    */
641   struct GNUNET_DISK_FileHandle *fh;
642
643   /**
644    * Overall size of the file.
645    */ 
646   uint64_t file_size;
647
648   /**
649    * When did we start?
650    */
651   struct GNUNET_TIME_Absolute start_time;
652
653   /**
654    * Hash of the file's contents (once
655    * computed).
656    */
657   GNUNET_HashCode file_id;
658  
659   /**
660    * Current operatinonal phase.
661    */
662   enum UnindexState state; 
663
664 };
665
666
667 /**
668  * Information we store for each search result.
669  */
670 struct SearchResult
671 {
672
673   /**
674    * URI to which this search result
675    * refers to.
676    */
677   struct GNUNET_FS_Uri *uri;
678
679   /**
680    * Metadata for the search result.
681    */
682   struct GNUNET_CONTAINER_MetaData *meta;
683
684   /**
685    * Client info for this search result.
686    */
687   void *client_info;
688
689   /**
690    * ID of a job that is currently probing
691    * this results' availability (NULL if we
692    * are not currently probing).
693    */
694   struct GNUNET_FS_DownloadContext *probe_ctx;
695   
696   /**
697    * ID of the task that will clean up the probe_ctx
698    * should it not complete on time (and that will
699    * need to be cancelled if we clean up the search
700    * result before then).
701    */
702   GNUNET_SCHEDULER_TaskIdentifier probe_cancel_task;
703
704   /**
705    * Number of mandatory keywords for which
706    * we have NOT yet found the search result;
707    * when this value hits zero, the search
708    * result is given to the callback.
709    */
710   uint32_t mandatory_missing;
711
712   /**
713    * Number of optional keywords under which
714    * this result was also found.
715    */
716   uint32_t optional_support;
717
718   /**
719    * Number of availability tests that
720    * have succeeded for this result.
721    */
722   uint32_t availability_success;
723
724   /**
725    * Number of availability trials that we
726    * have performed for this search result.
727    */
728   uint32_t availability_trials;
729
730 };
731
732
733 /**
734  * Information we keep for each keyword in
735  * a keyword search.
736  */
737 struct SearchRequestEntry
738 {
739   /**
740    * Hash of the original keyword, also known as the
741    * key (for decrypting the KBlock).
742    */
743   GNUNET_HashCode key;
744
745   /**
746    * Hash of the public key, also known as the query.
747    */
748   GNUNET_HashCode query;  
749
750   /**
751    * Map that contains a "struct SearchResult" for each result that
752    * was found under this keyword.  Note that the entries will point
753    * to the same locations as those in the master result map (in
754    * "struct GNUNET_FS_SearchContext"), so they should not be freed.
755    * The key for each entry is the XOR of the key and query in the CHK
756    * URI (as a unique identifier for the search result).
757    */
758   struct GNUNET_CONTAINER_MultiHashMap *results;
759
760   /**
761    * Is this keyword a mandatory keyword
762    * (started with '+')?
763    */
764   int mandatory;
765
766 };
767
768
769 /**
770  * Handle for controlling a search.
771  */
772 struct GNUNET_FS_SearchContext
773 {
774   /**
775    * Handle to the global FS context.
776    */
777   struct GNUNET_FS_Handle *h;
778
779   /**
780    * List of keywords that we're looking for.
781    */
782   struct GNUNET_FS_Uri *uri;
783
784   /**
785    * For update-searches, link to the
786    * base-SKS search that triggered the
787    * update search; otherwise NULL.
788    */
789   struct GNUNET_FS_SearchContext *parent;
790
791   /**
792    * Connection to the FS service.
793    */
794   struct GNUNET_CLIENT_Connection *client;
795
796   /**
797    * Pointer we keep for the client.
798    */
799   void *client_info;
800
801   /**
802    * Map that contains a "struct SearchResult" for each result that
803    * was found in the search.  The key for each entry is the XOR of
804    * the key and query in the CHK URI (as a unique identifier for the
805    * search result).
806    */
807   struct GNUNET_CONTAINER_MultiHashMap *master_result_map;
808
809   /**
810    * Per-keyword information for a keyword search.
811    * This array will have exactly as many entries
812    * as there were keywords.
813    */
814   struct SearchRequestEntry *requests;
815   
816   /**
817    * When did we start?
818    */
819   struct GNUNET_TIME_Absolute start_time;
820
821   /**
822    * ID of a task that is using this struct
823    * and that must be cancelled when the search
824    * is being stopped (if not GNUNET_SCHEDULER_NO_TASK).
825    * Used for the task that adds some artificial
826    * delay when trying to reconnect to the FS
827    * service.
828    */
829   GNUNET_SCHEDULER_TaskIdentifier task;
830   
831   /**
832    * Anonymity level for the search.
833    */
834   uint32_t anonymity;
835
836   /**
837    * Number of mandatory keywords in this query.
838    */
839   uint32_t mandatory_count;
840 };
841
842
843 /**
844  * Information about an active download request.
845  */ 
846 struct DownloadRequest
847 {
848   /**
849    * While pending, we keep all download requests
850    * in a linked list.
851    */
852   struct DownloadRequest *next;
853
854   /**
855    * CHK for the request.
856    */
857   struct ContentHashKey chk;
858
859   /**
860    * Offset of the corresponding block.
861    */
862   uint64_t offset;
863
864   /**
865    * Depth of the corresponding block in the tree.
866    */
867   unsigned int depth;
868
869   /**
870    * Set if this request is currently in the linked list of pending
871    * requests.  Needed in case we get a response for a request that we
872    * have not yet send (due to FS bug or two blocks with identical
873    * content); in this case, we would need to remove the block from
874    * the pending list (and need a fast way to check if the block is on
875    * it).
876    */
877   int is_pending;
878
879 };
880
881
882 /**
883  * Context for controlling a download.
884  */
885 struct GNUNET_FS_DownloadContext
886 {
887   
888   /**
889    * Global FS context.
890    */ 
891   struct GNUNET_FS_Handle *h;
892   
893   /**
894    * Connection to the FS service.
895    */
896   struct GNUNET_CLIENT_Connection *client;
897
898   /**
899    * Parent download (used when downloading files
900    * in directories).
901    */
902   struct GNUNET_FS_DownloadContext *parent;
903
904   /**
905    * Context kept for the client.
906    */
907   void *client_info;
908
909   /**
910    * URI that identifies the file that
911    * we are downloading.
912    */
913   struct GNUNET_FS_Uri *uri;
914
915   /**
916    * Known meta-data for the file (can be NULL).
917    */
918   struct GNUNET_CONTAINER_MetaData *meta;
919
920   /**
921    * Error message, NULL if we're doing OK.
922    */
923   char *emsg;
924
925   /**
926    * Where are we writing the data (name of the
927    * file, can be NULL!).
928    */
929   char *filename;
930
931   /**
932    * Map of active requests (those waiting
933    * for a response).  The key is the hash
934    * of the encryped block (aka query).
935    */
936   struct GNUNET_CONTAINER_MultiHashMap *active;
937
938   /**
939    * Linked list of pending requests.
940    */
941   struct DownloadRequest *pending;
942
943   /**
944    * The file handle, NULL if we don't create
945    * a file.
946    */
947   struct GNUNET_DISK_FileHandle *handle;
948
949   /**
950    * Non-NULL if we are currently having a request for
951    * transmission pending with the client handle.
952    */
953   struct GNUNET_CONNECTION_TransmitHandle *th;
954
955   /**
956    * Identity of the peer having the content, or all-zeros
957    * if we don't know of such a peer.
958    */
959   struct GNUNET_PeerIdentity target;
960
961   /**
962    * ID of a task that is using this struct
963    * and that must be cancelled when the download
964    * is being stopped (if not GNUNET_SCHEDULER_NO_TASK).
965    * Used for the task that adds some artificial
966    * delay when trying to reconnect to the FS
967    * service.
968    */
969   GNUNET_SCHEDULER_TaskIdentifier task;
970
971   /**
972    * What was the size of the file on disk that we're downloading
973    * before we started?  Used to detect if there is a point in
974    * checking an existing block on disk for matching the desired
975    * content.  0 if the file did not exist already.
976    */
977   uint64_t old_file_size;
978
979   /**
980    * What is the first offset that we're interested
981    * in?
982    */
983   uint64_t offset;
984
985   /**
986    * How many bytes starting from offset are desired?
987    * This is NOT the overall length of the file!
988    */
989   uint64_t length;
990
991   /**
992    * How many bytes have we already received within
993    * the specified range (DBlocks only).
994    */
995   uint64_t completed;
996
997   /**
998    * Time download was started.
999    */
1000   struct GNUNET_TIME_Absolute start_time;
1001
1002   /**
1003    * Desired level of anonymity.
1004    */
1005   uint32_t anonymity;
1006
1007   /**
1008    * The depth of the file-tree.
1009    */
1010   unsigned int treedepth;
1011
1012   /**
1013    * Options for the download.
1014    */
1015   enum GNUNET_FS_DownloadOptions options;
1016
1017 };
1018
1019 struct GNUNET_FS_Namespace
1020 {
1021
1022   /**
1023    * Private key for the namespace.
1024    */
1025   struct GNUNET_CRYPTO_RsaPrivateKey *key;
1026
1027   /**
1028    * Reference counter.
1029    */
1030   unsigned int rc;
1031 };
1032
1033
1034 /**
1035  * @brief index block (indexing a DBlock that 
1036  *        can be obtained directly from reading
1037  *        the plaintext file)
1038  */
1039 struct OnDemandBlock
1040 {
1041   /**
1042    * Hash code of the entire content of the
1043    * file that was indexed (used to uniquely
1044    * identify the plaintext file).
1045    */
1046   GNUNET_HashCode file_id;
1047
1048   /**
1049    * At which offset should we be able to find
1050    * this on-demand encoded block?
1051    */
1052   uint64_t offset GNUNET_PACKED;
1053
1054 };
1055
1056
1057 /**
1058  * @brief keyword block (advertising data under a keyword)
1059  */
1060 struct KBlock
1061 {
1062
1063   /**
1064    * GNUNET_RSA_Signature using RSA-key generated from search keyword.
1065    */
1066   struct GNUNET_CRYPTO_RsaSignature signature;
1067
1068   /**
1069    * What is being signed and why?
1070    */
1071   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
1072
1073   /**
1074    * Key generated (!) from the H(keyword) as the seed!
1075    */
1076   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded keyspace;
1077
1078   /* 0-terminated URI here */
1079
1080   /* variable-size Meta-Data follows here */
1081
1082 };
1083
1084 /**
1085  * @brief namespace content block (advertising data under an identifier in a namespace)
1086  */
1087 struct SBlock
1088 {
1089
1090   /**
1091    * GNUNET_RSA_Signature using RSA-key of the namespace
1092    */
1093   struct GNUNET_CRYPTO_RsaSignature signature;
1094
1095   /**
1096    * What is being signed and why?
1097    */
1098   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
1099
1100   /**
1101    * Hash of the hash of the human-readable identifier used for
1102    * this entry (the hash of the human-readable identifier is
1103    * used as the key for decryption; the xor of this identifier
1104    * and the hash of the "keyspace" is the datastore-query hash).
1105    */
1106   GNUNET_HashCode identifier;
1107
1108   /**
1109    * Public key of the namespace.
1110    */
1111   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded subspace;
1112
1113   /* 0-terminated update-identifier here */
1114
1115   /* 0-terminated URI here */
1116
1117   /* variable-size Meta-Data follows here */
1118
1119 };
1120
1121
1122 /**
1123  * Message sent from a GNUnet (fs) publishing
1124  * activity to the gnunet-fs-service to 
1125  * initiate indexing of a file.  The service
1126  * is supposed to check if the specified file
1127  * is available and has the same cryptographic
1128  * hash.  It should then respond with either
1129  * a confirmation or a denial.
1130  *
1131  * On OSes where this works, it is considered
1132  * acceptable if the service only checks that
1133  * the path, device and inode match (it can
1134  * then be assumed that the hash will also match
1135  * without actually computing it; this is an
1136  * optimization that should be safe given that
1137  * the client is not our adversary).
1138  */
1139 struct IndexStartMessage
1140 {
1141
1142   /**
1143    * Message type will be 
1144    * GNUNET_MESSAGE_TYPE_FS_INDEX_START.
1145    */
1146   struct GNUNET_MessageHeader header;
1147
1148   /**
1149    * ID of device containing the file, as seen by the client.  This
1150    * device ID is obtained using a call like "statvfs" (and converting
1151    * the "f_fsid" field to a 32-bit big-endian number).  Use 0 if the
1152    * OS does not support this, in which case the service must do a
1153    * full hash recomputation.
1154    */
1155   uint32_t device GNUNET_PACKED;
1156   
1157   /**
1158    * Inode of the file on the given device, as seen by the client
1159    * ("st_ino" field from "struct stat").  Use 0 if the OS does not
1160    * support this, in which case the service must do a full hash
1161    * recomputation.
1162    */
1163   uint64_t inode GNUNET_PACKED;
1164
1165   /**
1166    * Hash of the file that we would like to index.
1167    */
1168   GNUNET_HashCode file_id;
1169
1170   /* this is followed by a 0-terminated
1171      filename of a file with the hash
1172      "file_id" as seen by the client */
1173
1174 };
1175
1176
1177 /**
1178  * Message send by FS service in response to a request
1179  * asking for a list of all indexed files.
1180  */
1181 struct IndexInfoMessage
1182 {
1183   /**
1184    * Message type will be 
1185    * GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY.
1186    */
1187   struct GNUNET_MessageHeader header;
1188
1189   /**
1190    * Always zero.
1191    */
1192   uint32_t reserved GNUNET_PACKED;
1193
1194   /**
1195    * Hash of the indexed file.
1196    */
1197   GNUNET_HashCode file_id;
1198
1199   /* this is followed by a 0-terminated
1200      filename of a file with the hash
1201      "file_id" as seen by the client */
1202   
1203 };
1204
1205
1206 /**
1207  * Message sent from a GNUnet (fs) unindexing
1208  * activity to the gnunet-fs-service to 
1209  * indicate that a file will be unindexed.  The service
1210  * is supposed to remove the file from the
1211  * list of indexed files and response with
1212  * a confirmation message (even if the file
1213  * was already not on the list).
1214  */
1215 struct UnindexMessage
1216 {
1217
1218   /**
1219    * Message type will be 
1220    * GNUNET_MESSAGE_TYPE_FS_UNINDEX.
1221    */
1222   struct GNUNET_MessageHeader header;
1223
1224   /**
1225    * Always zero.
1226    */
1227   uint32_t reserved GNUNET_PACKED;
1228
1229   /**
1230    * Hash of the file that we will unindex.
1231    */
1232   GNUNET_HashCode file_id;
1233
1234 };
1235
1236
1237 /**
1238  * Message sent from a GNUnet (fs) search
1239  * activity to the gnunet-fs-service to 
1240  * start a search.
1241  */
1242 struct SearchMessage
1243 {
1244
1245   /**
1246    * Message type will be 
1247    * GNUNET_MESSAGE_TYPE_FS_START_SEARCH.
1248    */
1249   struct GNUNET_MessageHeader header;
1250
1251   /**
1252    * Should be zero.
1253    */
1254   int32_t reserved GNUNET_PACKED;
1255
1256   /**
1257    * Type of the content that we're looking for.
1258    * 0 for any.
1259    */
1260   uint32_t type GNUNET_PACKED;
1261
1262   /**
1263    * Desired anonymity level, big-endian.
1264    */
1265   uint32_t anonymity_level GNUNET_PACKED;
1266
1267   /**
1268    * If the request is for a DBLOCK or IBLOCK, this is the identity of
1269    * the peer that is known to have a response.  Set to all-zeros if
1270    * such a target is not known (note that even if OUR anonymity
1271    * level is >0 we may happen to know the responder's identity;
1272    * nevertheless, we should probably not use it for a DHT-lookup
1273    * or similar blunt actions in order to avoid exposing ourselves).
1274    * <p>
1275    * If the request is for an SBLOCK, this is the identity of the
1276    * pseudonym to which the SBLOCK belongs. 
1277    * <p>
1278    * If the request is for a KBLOCK, "target" must be all zeros.
1279    */
1280   GNUNET_HashCode target;
1281
1282   /**
1283    * Hash of the keyword (aka query) for KBLOCKs; Hash of
1284    * the CHK-encoded block for DBLOCKS and IBLOCKS (aka query)
1285    * and hash of the identifier XORed with the target for
1286    * SBLOCKS (aka query).
1287    */
1288   GNUNET_HashCode query;
1289
1290   /* this is followed by the hash codes of already-known
1291      results (which should hence be excluded from what
1292      the service returns); naturally, this only applies
1293      to queries that can have multiple results, such as
1294      those for KBLOCKS (KSK) and SBLOCKS (SKS) */
1295 };
1296
1297
1298 /**
1299  * Response from FS service with a result for
1300  * a previous FS search.  Note that queries
1301  * for DBLOCKS and IBLOCKS that have received
1302  * a single response are considered done.
1303  */
1304 struct ContentMessage
1305 {
1306
1307   /**
1308    * Message type will be 
1309    * GNUNET_MESSAGE_TYPE_FS_CONTENT.
1310    */
1311   struct GNUNET_MessageHeader header;
1312
1313   /**
1314    * Type of the content that was found,
1315    * should never be 0.
1316    */
1317   uint32_t type GNUNET_PACKED;
1318
1319   /**
1320    * When will this result expire?
1321    */
1322   struct GNUNET_TIME_AbsoluteNBO expiration;
1323
1324   /* followed by the actual block of data */
1325
1326 };
1327
1328 /**
1329  * Only the (mandatory) query is included.
1330  */
1331 #define GET_MESSAGE_BIT_QUERY_ONLY 0
1332
1333 /**
1334  * The peer identity of a peer waiting for the
1335  * reply is included (used if the response
1336  * should be transmitted to someone other than
1337  * the sender of the GET).
1338  */
1339 #define GET_MESSAGE_BIT_RETURN_TO 1
1340
1341 /**
1342  * The hash of the public key of the target
1343  * namespace is included (for SKS queries).
1344  */
1345 #define GET_MESSAGE_BIT_SKS_NAMESPACE 2
1346
1347 /**
1348  * The peer identity of a peer that had claimed to have the content
1349  * previously is included (can be used if responder-anonymity is not
1350  * desired; note that the precursor presumably lacked a direct
1351  * connection to the specified peer; still, the receiver is in no way
1352  * required to limit forwarding only to the specified peer, it should
1353  * only prefer it somewhat if possible).
1354  */
1355 #define GET_MESSAGE_BIT_TRANSMIT_TO 4
1356
1357
1358 /**
1359  * Message sent between peers asking for FS-content.
1360  */
1361 struct GetMessage
1362 {
1363
1364   /**
1365    * Message type will be GNUNET_MESSAGE_TYPE_FS_GET.
1366    */
1367   struct GNUNET_MessageHeader header;
1368
1369   /**
1370    * Type of the query (block type).
1371    */
1372   uint32_t type GNUNET_PACKED;
1373
1374   /**
1375    * How important is this request (network byte order)
1376    */
1377   uint32_t priority GNUNET_PACKED;
1378
1379   /**
1380    * Relative time to live in GNUNET_CRON_MILLISECONDS (network byte order)
1381    */
1382   int32_t ttl GNUNET_PACKED;
1383
1384   /**
1385    * The content hash should be mutated using this value
1386    * before checking against the bloomfilter (used to
1387    * get many different filters for the same hash codes).
1388    * The number should be in big-endian format when used
1389    * for mingling.
1390    */
1391   int32_t filter_mutator GNUNET_PACKED;
1392
1393   /**
1394    * Which of the optional hash codes are present at the end of the
1395    * message?  See GET_MESSAGE_BIT_xx constants.  For each bit that is
1396    * set, an additional GNUNET_HashCode with the respective content
1397    * (in order of the bits) will be appended to the end of the GET
1398    * message.
1399    */
1400   uint32_t hash_bitmap GNUNET_PACKED;
1401
1402   /**
1403    * Hashcodes of the file(s) we're looking for.
1404    * Details depend on the query type.
1405    */
1406   GNUNET_HashCode query GNUNET_PACKED;
1407
1408   /* this is followed by hash codes
1409      as specified in the  "hash_bitmap";
1410      after that, an optional bloomfilter
1411      (with bits set for replies that should
1412      be suppressed) can be present */
1413 };
1414
1415
1416 /**
1417  * Message sent between peers providing FS-content.
1418  */
1419 struct PutMessage
1420 {
1421
1422   /**
1423    * Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
1424    */
1425   struct GNUNET_MessageHeader header;
1426
1427   /**
1428    * Type of the block (in big endian).
1429    */
1430   uint32_t type GNUNET_PACKED;
1431
1432   /**
1433    * When does this result expire? 
1434    */
1435   struct GNUNET_TIME_RelativeNBO expiration;
1436
1437   /* this is followed by the actual encrypted content */
1438
1439 };
1440
1441
1442 #endif
1443
1444 /* end of fs.h */