fixing bugs, diagnosis summary
[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    * Argument to pass to the client in callbacks.
483    */
484   void *client_ctx;
485   
486   /**
487    * File-structure that is being shared.
488    */
489   struct GNUNET_FS_FileInformation *fi;
490
491   /**
492    * Namespace that we are publishing in, NULL if we have no namespace.
493    */
494   struct GNUNET_FS_Namespace *namespace;
495
496   /**
497    * ID of the content in the namespace, NULL if we have no namespace.
498    */
499   char *nid;
500
501   /**
502    * ID for future updates, NULL if we have no namespace or no updates.
503    */
504   char *nuid;
505
506   /**
507    * Our own client handle for the FS service;
508    * only briefly used when we start to index a
509    * file, otherwise NULL.
510    */
511   struct GNUNET_CLIENT_Connection *client;
512
513   /**
514    * Current position in the file-tree for the
515    * upload.
516    */
517   struct GNUNET_FS_FileInformation *fi_pos;
518
519   /**
520    * Connection to the datastore service.
521    */
522   struct GNUNET_DATASTORE_Handle *dsh;
523
524   /**
525    * ID of the task performing the upload. NO_TASK
526    * if the upload has completed.
527    */
528   GNUNET_SCHEDULER_TaskIdentifier upload_task;
529
530   /**
531    * Typically GNUNET_NO.  Set to GNUNET_YES if
532    * "upload_task" is GNUNET_SCHEDULER_NO_TASK
533    * and we're waiting for a response from the
534    * datastore service (in which case this
535    * struct must not be freed until we have that
536    * response).  If someone tries to stop the
537    * download for good during this period, 
538    * "in_network_wait" is set to GNUNET_SYSERR
539    * which will cause the struct to be destroyed
540    * right after we have the reply (or timeout)
541    * from the datastore service.
542    */
543   int in_network_wait;
544
545   /**
546    * Options for publishing.
547    */
548   enum GNUNET_FS_PublishOptions options;
549
550   /**
551    * Space reservation ID with datastore service
552    * for this upload.
553    */
554   int rid;
555
556   /**
557    * Set to GNUNET_YES if all processing has completed.
558    */
559   int all_done;
560 };
561
562
563 /**
564  * Phases of unindex processing (state machine).
565  */ 
566 enum UnindexState
567   {
568     /**
569      * We're currently hashing the file.
570      */
571     UNINDEX_STATE_HASHING = 0,
572
573     /**
574      * We're notifying the FS service about
575      * the unindexing.
576      */
577     UNINDEX_STATE_FS_NOTIFY = 1,
578
579     /**
580      * We're telling the datastore to delete
581      * the respective entries.
582      */
583     UNINDEX_STATE_DS_REMOVE = 2,
584
585     /**
586      * We're done.
587      */
588     UNINDEX_STATE_COMPLETE = 3,
589
590     /**
591      * We've encountered a fatal error.
592      */
593     UNINDEX_STATE_ERROR = 4,
594
595     /**
596      * We've been aborted.  The next callback should clean up the
597      * struct.
598      */
599     UNINDEX_STATE_ABORTED = 5
600   };
601
602
603 /**
604  * Handle for controlling an unindexing operation.
605  */
606 struct GNUNET_FS_UnindexContext
607 {
608   
609   /**
610    * Global FS context.
611    */
612   struct GNUNET_FS_Handle *h;
613
614   /**
615    * Name of the file that we are unindexing.
616    */
617   char *filename;
618
619   /**
620    * Connection to the FS service,
621    * only valid during the UNINDEX_STATE_FS_NOTIFY
622    * phase.
623    */
624   struct GNUNET_CLIENT_Connection *client;
625
626   /**
627    * Connection to the datastore service,
628    * only valid during the UNINDEX_STATE_DS_NOTIFY
629    * phase.
630    */
631   struct GNUNET_DATASTORE_Handle *dsh;
632
633   /**
634    * Pointer kept for the client.
635    */
636   void *client_info;
637
638   /**
639    * Merkle-ish tree encoder context.
640    */
641   struct GNUNET_FS_TreeEncoder *tc;
642
643   /**
644    * Handle used to read the file.
645    */
646   struct GNUNET_DISK_FileHandle *fh;
647
648   /**
649    * Overall size of the file.
650    */ 
651   uint64_t file_size;
652
653   /**
654    * When did we start?
655    */
656   struct GNUNET_TIME_Absolute start_time;
657
658   /**
659    * Hash of the file's contents (once
660    * computed).
661    */
662   GNUNET_HashCode file_id;
663  
664   /**
665    * Current operatinonal phase.
666    */
667   enum UnindexState state; 
668
669 };
670
671
672 /**
673  * Information we store for each search result.
674  */
675 struct SearchResult
676 {
677
678   /**
679    * URI to which this search result
680    * refers to.
681    */
682   struct GNUNET_FS_Uri *uri;
683
684   /**
685    * Metadata for the search result.
686    */
687   struct GNUNET_CONTAINER_MetaData *meta;
688
689   /**
690    * Client info for this search result.
691    */
692   void *client_info;
693
694   /**
695    * ID of a job that is currently probing
696    * this results' availability (NULL if we
697    * are not currently probing).
698    */
699   struct GNUNET_FS_DownloadContext *probe_ctx;
700   
701   /**
702    * ID of the task that will clean up the probe_ctx
703    * should it not complete on time (and that will
704    * need to be cancelled if we clean up the search
705    * result before then).
706    */
707   GNUNET_SCHEDULER_TaskIdentifier probe_cancel_task;
708
709   /**
710    * Number of mandatory keywords for which
711    * we have NOT yet found the search result;
712    * when this value hits zero, the search
713    * result is given to the callback.
714    */
715   uint32_t mandatory_missing;
716
717   /**
718    * Number of optional keywords under which
719    * this result was also found.
720    */
721   uint32_t optional_support;
722
723   /**
724    * Number of availability tests that
725    * have succeeded for this result.
726    */
727   uint32_t availability_success;
728
729   /**
730    * Number of availability trials that we
731    * have performed for this search result.
732    */
733   uint32_t availability_trials;
734
735 };
736
737
738 /**
739  * Information we keep for each keyword in
740  * a keyword search.
741  */
742 struct SearchRequestEntry
743 {
744   /**
745    * Hash of the original keyword, also known as the
746    * key (for decrypting the KBlock).
747    */
748   GNUNET_HashCode key;
749
750   /**
751    * Hash of the public key, also known as the query.
752    */
753   GNUNET_HashCode query;  
754
755   /**
756    * Map that contains a "struct SearchResult" for each result that
757    * was found under this keyword.  Note that the entries will point
758    * to the same locations as those in the master result map (in
759    * "struct GNUNET_FS_SearchContext"), so they should not be freed.
760    * The key for each entry is the XOR of the key and query in the CHK
761    * URI (as a unique identifier for the search result).
762    */
763   struct GNUNET_CONTAINER_MultiHashMap *results;
764
765   /**
766    * Is this keyword a mandatory keyword
767    * (started with '+')?
768    */
769   int mandatory;
770
771 };
772
773
774 /**
775  * Handle for controlling a search.
776  */
777 struct GNUNET_FS_SearchContext
778 {
779   /**
780    * Handle to the global FS context.
781    */
782   struct GNUNET_FS_Handle *h;
783
784   /**
785    * List of keywords that we're looking for.
786    */
787   struct GNUNET_FS_Uri *uri;
788
789   /**
790    * For update-searches, link to the
791    * base-SKS search that triggered the
792    * update search; otherwise NULL.
793    */
794   struct GNUNET_FS_SearchContext *parent;
795
796   /**
797    * Connection to the FS service.
798    */
799   struct GNUNET_CLIENT_Connection *client;
800
801   /**
802    * Pointer we keep for the client.
803    */
804   void *client_info;
805
806   /**
807    * Map that contains a "struct SearchResult" for each result that
808    * was found in the search.  The key for each entry is the XOR of
809    * the key and query in the CHK URI (as a unique identifier for the
810    * search result).
811    */
812   struct GNUNET_CONTAINER_MultiHashMap *master_result_map;
813
814   /**
815    * Per-keyword information for a keyword search.
816    * This array will have exactly as many entries
817    * as there were keywords.
818    */
819   struct SearchRequestEntry *requests;
820   
821   /**
822    * When did we start?
823    */
824   struct GNUNET_TIME_Absolute start_time;
825
826   /**
827    * ID of a task that is using this struct
828    * and that must be cancelled when the search
829    * is being stopped (if not GNUNET_SCHEDULER_NO_TASK).
830    * Used for the task that adds some artificial
831    * delay when trying to reconnect to the FS
832    * service.
833    */
834   GNUNET_SCHEDULER_TaskIdentifier task;
835   
836   /**
837    * Anonymity level for the search.
838    */
839   uint32_t anonymity;
840
841   /**
842    * Number of mandatory keywords in this query.
843    */
844   uint32_t mandatory_count;
845 };
846
847
848 /**
849  * Information about an active download request.
850  */ 
851 struct DownloadRequest
852 {
853   /**
854    * While pending, we keep all download requests
855    * in a linked list.
856    */
857   struct DownloadRequest *next;
858
859   /**
860    * CHK for the request.
861    */
862   struct ContentHashKey chk;
863
864   /**
865    * Offset of the corresponding block.
866    */
867   uint64_t offset;
868
869   /**
870    * Depth of the corresponding block in the tree.
871    */
872   unsigned int depth;
873
874   /**
875    * Set if this request is currently in the linked list of pending
876    * requests.  Needed in case we get a response for a request that we
877    * have not yet send (due to FS bug or two blocks with identical
878    * content); in this case, we would need to remove the block from
879    * the pending list (and need a fast way to check if the block is on
880    * it).
881    */
882   int is_pending;
883
884 };
885
886
887 /**
888  * Context for controlling a download.
889  */
890 struct GNUNET_FS_DownloadContext
891 {
892   
893   /**
894    * Global FS context.
895    */ 
896   struct GNUNET_FS_Handle *h;
897   
898   /**
899    * Connection to the FS service.
900    */
901   struct GNUNET_CLIENT_Connection *client;
902
903   /**
904    * Parent download (used when downloading files
905    * in directories).
906    */
907   struct GNUNET_FS_DownloadContext *parent;
908
909   /**
910    * Context kept for the client.
911    */
912   void *client_info;
913
914   /**
915    * URI that identifies the file that
916    * we are downloading.
917    */
918   struct GNUNET_FS_Uri *uri;
919
920   /**
921    * Known meta-data for the file (can be NULL).
922    */
923   struct GNUNET_CONTAINER_MetaData *meta;
924
925   /**
926    * Error message, NULL if we're doing OK.
927    */
928   char *emsg;
929
930   /**
931    * Where are we writing the data (name of the
932    * file, can be NULL!).
933    */
934   char *filename;
935
936   /**
937    * Map of active requests (those waiting
938    * for a response).  The key is the hash
939    * of the encryped block (aka query).
940    */
941   struct GNUNET_CONTAINER_MultiHashMap *active;
942
943   /**
944    * Linked list of pending requests.
945    */
946   struct DownloadRequest *pending;
947
948   /**
949    * The file handle, NULL if we don't create
950    * a file.
951    */
952   struct GNUNET_DISK_FileHandle *handle;
953
954   /**
955    * Non-NULL if we are currently having a request for
956    * transmission pending with the client handle.
957    */
958   struct GNUNET_CONNECTION_TransmitHandle *th;
959
960   /**
961    * Identity of the peer having the content, or all-zeros
962    * if we don't know of such a peer.
963    */
964   struct GNUNET_PeerIdentity target;
965
966   /**
967    * ID of a task that is using this struct
968    * and that must be cancelled when the download
969    * is being stopped (if not GNUNET_SCHEDULER_NO_TASK).
970    * Used for the task that adds some artificial
971    * delay when trying to reconnect to the FS
972    * service.
973    */
974   GNUNET_SCHEDULER_TaskIdentifier task;
975
976   /**
977    * What was the size of the file on disk that we're downloading
978    * before we started?  Used to detect if there is a point in
979    * checking an existing block on disk for matching the desired
980    * content.  0 if the file did not exist already.
981    */
982   uint64_t old_file_size;
983
984   /**
985    * What is the first offset that we're interested
986    * in?
987    */
988   uint64_t offset;
989
990   /**
991    * How many bytes starting from offset are desired?
992    * This is NOT the overall length of the file!
993    */
994   uint64_t length;
995
996   /**
997    * How many bytes have we already received within
998    * the specified range (DBlocks only).
999    */
1000   uint64_t completed;
1001
1002   /**
1003    * Time download was started.
1004    */
1005   struct GNUNET_TIME_Absolute start_time;
1006
1007   /**
1008    * Desired level of anonymity.
1009    */
1010   uint32_t anonymity;
1011
1012   /**
1013    * The depth of the file-tree.
1014    */
1015   unsigned int treedepth;
1016
1017   /**
1018    * Options for the download.
1019    */
1020   enum GNUNET_FS_DownloadOptions options;
1021
1022 };
1023
1024 struct GNUNET_FS_Namespace
1025 {
1026
1027   /**
1028    * Private key for the namespace.
1029    */
1030   struct GNUNET_CRYPTO_RsaPrivateKey *key;
1031
1032   /**
1033    * Reference counter.
1034    */
1035   unsigned int rc;
1036 };
1037
1038
1039 /**
1040  * @brief index block (indexing a DBlock that 
1041  *        can be obtained directly from reading
1042  *        the plaintext file)
1043  */
1044 struct OnDemandBlock
1045 {
1046   /**
1047    * Hash code of the entire content of the
1048    * file that was indexed (used to uniquely
1049    * identify the plaintext file).
1050    */
1051   GNUNET_HashCode file_id;
1052
1053   /**
1054    * At which offset should we be able to find
1055    * this on-demand encoded block?
1056    */
1057   uint64_t offset GNUNET_PACKED;
1058
1059 };
1060
1061
1062 /**
1063  * @brief keyword block (advertising data under a keyword)
1064  */
1065 struct KBlock
1066 {
1067
1068   /**
1069    * GNUNET_RSA_Signature using RSA-key generated from search keyword.
1070    */
1071   struct GNUNET_CRYPTO_RsaSignature signature;
1072
1073   /**
1074    * What is being signed and why?
1075    */
1076   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
1077
1078   /**
1079    * Key generated (!) from the H(keyword) as the seed!
1080    */
1081   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded keyspace;
1082
1083   /* 0-terminated URI here */
1084
1085   /* variable-size Meta-Data follows here */
1086
1087 };
1088
1089 /**
1090  * @brief namespace content block (advertising data under an identifier in a namespace)
1091  */
1092 struct SBlock
1093 {
1094
1095   /**
1096    * GNUNET_RSA_Signature using RSA-key of the namespace
1097    */
1098   struct GNUNET_CRYPTO_RsaSignature signature;
1099
1100   /**
1101    * What is being signed and why?
1102    */
1103   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
1104
1105   /**
1106    * Hash of the hash of the human-readable identifier used for
1107    * this entry (the hash of the human-readable identifier is
1108    * used as the key for decryption; the xor of this identifier
1109    * and the hash of the "keyspace" is the datastore-query hash).
1110    */
1111   GNUNET_HashCode identifier;
1112
1113   /**
1114    * Public key of the namespace.
1115    */
1116   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded subspace;
1117
1118   /* 0-terminated update-identifier here */
1119
1120   /* 0-terminated URI here */
1121
1122   /* variable-size Meta-Data follows here */
1123
1124 };
1125
1126
1127 /**
1128  * Message sent from a GNUnet (fs) publishing
1129  * activity to the gnunet-fs-service to 
1130  * initiate indexing of a file.  The service
1131  * is supposed to check if the specified file
1132  * is available and has the same cryptographic
1133  * hash.  It should then respond with either
1134  * a confirmation or a denial.
1135  *
1136  * On OSes where this works, it is considered
1137  * acceptable if the service only checks that
1138  * the path, device and inode match (it can
1139  * then be assumed that the hash will also match
1140  * without actually computing it; this is an
1141  * optimization that should be safe given that
1142  * the client is not our adversary).
1143  */
1144 struct IndexStartMessage
1145 {
1146
1147   /**
1148    * Message type will be 
1149    * GNUNET_MESSAGE_TYPE_FS_INDEX_START.
1150    */
1151   struct GNUNET_MessageHeader header;
1152
1153   /**
1154    * ID of device containing the file, as seen by the client.  This
1155    * device ID is obtained using a call like "statvfs" (and converting
1156    * the "f_fsid" field to a 32-bit big-endian number).  Use 0 if the
1157    * OS does not support this, in which case the service must do a
1158    * full hash recomputation.
1159    */
1160   uint32_t device GNUNET_PACKED;
1161   
1162   /**
1163    * Inode of the file on the given device, as seen by the client
1164    * ("st_ino" field from "struct stat").  Use 0 if the OS does not
1165    * support this, in which case the service must do a full hash
1166    * recomputation.
1167    */
1168   uint64_t inode GNUNET_PACKED;
1169
1170   /**
1171    * Hash of the file that we would like to index.
1172    */
1173   GNUNET_HashCode file_id;
1174
1175   /* this is followed by a 0-terminated
1176      filename of a file with the hash
1177      "file_id" as seen by the client */
1178
1179 };
1180
1181
1182 /**
1183  * Message send by FS service in response to a request
1184  * asking for a list of all indexed files.
1185  */
1186 struct IndexInfoMessage
1187 {
1188   /**
1189    * Message type will be 
1190    * GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY.
1191    */
1192   struct GNUNET_MessageHeader header;
1193
1194   /**
1195    * Always zero.
1196    */
1197   uint32_t reserved GNUNET_PACKED;
1198
1199   /**
1200    * Hash of the indexed file.
1201    */
1202   GNUNET_HashCode file_id;
1203
1204   /* this is followed by a 0-terminated
1205      filename of a file with the hash
1206      "file_id" as seen by the client */
1207   
1208 };
1209
1210
1211 /**
1212  * Message sent from a GNUnet (fs) unindexing
1213  * activity to the gnunet-fs-service to 
1214  * indicate that a file will be unindexed.  The service
1215  * is supposed to remove the file from the
1216  * list of indexed files and response with
1217  * a confirmation message (even if the file
1218  * was already not on the list).
1219  */
1220 struct UnindexMessage
1221 {
1222
1223   /**
1224    * Message type will be 
1225    * GNUNET_MESSAGE_TYPE_FS_UNINDEX.
1226    */
1227   struct GNUNET_MessageHeader header;
1228
1229   /**
1230    * Always zero.
1231    */
1232   uint32_t reserved GNUNET_PACKED;
1233
1234   /**
1235    * Hash of the file that we will unindex.
1236    */
1237   GNUNET_HashCode file_id;
1238
1239 };
1240
1241
1242 /**
1243  * Message sent from a GNUnet (fs) search
1244  * activity to the gnunet-fs-service to 
1245  * start a search.
1246  */
1247 struct SearchMessage
1248 {
1249
1250   /**
1251    * Message type will be 
1252    * GNUNET_MESSAGE_TYPE_FS_START_SEARCH.
1253    */
1254   struct GNUNET_MessageHeader header;
1255
1256   /**
1257    * Should be zero.
1258    */
1259   int32_t reserved GNUNET_PACKED;
1260
1261   /**
1262    * Type of the content that we're looking for.
1263    * 0 for any.
1264    */
1265   uint32_t type GNUNET_PACKED;
1266
1267   /**
1268    * Desired anonymity level, big-endian.
1269    */
1270   uint32_t anonymity_level GNUNET_PACKED;
1271
1272   /**
1273    * If the request is for a DBLOCK or IBLOCK, this is the identity of
1274    * the peer that is known to have a response.  Set to all-zeros if
1275    * such a target is not known (note that even if OUR anonymity
1276    * level is >0 we may happen to know the responder's identity;
1277    * nevertheless, we should probably not use it for a DHT-lookup
1278    * or similar blunt actions in order to avoid exposing ourselves).
1279    * <p>
1280    * If the request is for an SBLOCK, this is the identity of the
1281    * pseudonym to which the SBLOCK belongs. 
1282    * <p>
1283    * If the request is for a KBLOCK, "target" must be all zeros.
1284    */
1285   GNUNET_HashCode target;
1286
1287   /**
1288    * Hash of the keyword (aka query) for KBLOCKs; Hash of
1289    * the CHK-encoded block for DBLOCKS and IBLOCKS (aka query)
1290    * and hash of the identifier XORed with the target for
1291    * SBLOCKS (aka query).
1292    */
1293   GNUNET_HashCode query;
1294
1295   /* this is followed by the hash codes of already-known
1296      results (which should hence be excluded from what
1297      the service returns); naturally, this only applies
1298      to queries that can have multiple results, such as
1299      those for KBLOCKS (KSK) and SBLOCKS (SKS) */
1300 };
1301
1302
1303 /**
1304  * Response from FS service with a result for
1305  * a previous FS search.  Note that queries
1306  * for DBLOCKS and IBLOCKS that have received
1307  * a single response are considered done.
1308  */
1309 struct ContentMessage
1310 {
1311
1312   /**
1313    * Message type will be 
1314    * GNUNET_MESSAGE_TYPE_FS_CONTENT.
1315    */
1316   struct GNUNET_MessageHeader header;
1317
1318   /**
1319    * Type of the content that was found,
1320    * should never be 0.
1321    */
1322   uint32_t type GNUNET_PACKED;
1323
1324   /**
1325    * When will this result expire?
1326    */
1327   struct GNUNET_TIME_AbsoluteNBO expiration;
1328
1329   /* followed by the actual block of data */
1330
1331 };
1332
1333 /**
1334  * Only the (mandatory) query is included.
1335  */
1336 #define GET_MESSAGE_BIT_QUERY_ONLY 0
1337
1338 /**
1339  * The peer identity of a peer waiting for the
1340  * reply is included (used if the response
1341  * should be transmitted to someone other than
1342  * the sender of the GET).
1343  */
1344 #define GET_MESSAGE_BIT_RETURN_TO 1
1345
1346 /**
1347  * The hash of the public key of the target
1348  * namespace is included (for SKS queries).
1349  */
1350 #define GET_MESSAGE_BIT_SKS_NAMESPACE 2
1351
1352 /**
1353  * The peer identity of a peer that had claimed to have the content
1354  * previously is included (can be used if responder-anonymity is not
1355  * desired; note that the precursor presumably lacked a direct
1356  * connection to the specified peer; still, the receiver is in no way
1357  * required to limit forwarding only to the specified peer, it should
1358  * only prefer it somewhat if possible).
1359  */
1360 #define GET_MESSAGE_BIT_TRANSMIT_TO 4
1361
1362
1363 /**
1364  * Message sent between peers asking for FS-content.
1365  */
1366 struct GetMessage
1367 {
1368
1369   /**
1370    * Message type will be GNUNET_MESSAGE_TYPE_FS_GET.
1371    */
1372   struct GNUNET_MessageHeader header;
1373
1374   /**
1375    * Type of the query (block type).
1376    */
1377   uint32_t type GNUNET_PACKED;
1378
1379   /**
1380    * How important is this request (network byte order)
1381    */
1382   uint32_t priority GNUNET_PACKED;
1383
1384   /**
1385    * Relative time to live in GNUNET_CRON_MILLISECONDS (network byte order)
1386    */
1387   int32_t ttl GNUNET_PACKED;
1388
1389   /**
1390    * The content hash should be mutated using this value
1391    * before checking against the bloomfilter (used to
1392    * get many different filters for the same hash codes).
1393    * The number should be in big-endian format when used
1394    * for mingling.
1395    */
1396   int32_t filter_mutator GNUNET_PACKED;
1397
1398   /**
1399    * Which of the optional hash codes are present at the end of the
1400    * message?  See GET_MESSAGE_BIT_xx constants.  For each bit that is
1401    * set, an additional GNUNET_HashCode with the respective content
1402    * (in order of the bits) will be appended to the end of the GET
1403    * message.
1404    */
1405   uint32_t hash_bitmap GNUNET_PACKED;
1406
1407   /**
1408    * Hashcodes of the file(s) we're looking for.
1409    * Details depend on the query type.
1410    */
1411   GNUNET_HashCode query GNUNET_PACKED;
1412
1413   /* this is followed by hash codes
1414      as specified in the  "hash_bitmap";
1415      after that, an optional bloomfilter
1416      (with bits set for replies that should
1417      be suppressed) can be present */
1418 };
1419
1420
1421 /**
1422  * Message sent between peers providing FS-content.
1423  */
1424 struct PutMessage
1425 {
1426
1427   /**
1428    * Message type will be GNUNET_MESSAGE_TYPE_FS_PUT.
1429    */
1430   struct GNUNET_MessageHeader header;
1431
1432   /**
1433    * Type of the block (in big endian).
1434    */
1435   uint32_t type GNUNET_PACKED;
1436
1437   /**
1438    * When does this result expire? 
1439    */
1440   struct GNUNET_TIME_RelativeNBO expiration;
1441
1442   /* this is followed by the actual encrypted content */
1443
1444 };
1445
1446
1447 #endif
1448
1449 /* end of fs.h */