diff options
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | src/fs/fs.h | 67 | ||||
-rw-r--r-- | src/fs/fs_namespace.c | 732 | ||||
-rw-r--r-- | src/fs/fs_publish.c | 219 |
4 files changed, 795 insertions, 227 deletions
@@ -17,8 +17,6 @@ | |||
17 | - derived key generation [Nils] | 17 | - derived key generation [Nils] |
18 | * PWNAT: [Nate/MW/Nils] | 18 | * PWNAT: [Nate/MW/Nils] |
19 | - W32 port | 19 | - W32 port |
20 | * FS: [CG] | ||
21 | - implement 'GNUNET_FS_namespace_list_updateable', reconsider API! | ||
22 | * GNUNET-GTK: [CG] | 20 | * GNUNET-GTK: [CG] |
23 | - namespaces: | 21 | - namespaces: |
24 | + namespace publishing | 22 | + namespace publishing |
@@ -34,8 +32,6 @@ | |||
34 | + handle 'lost parent' case for recursive downloads (need to move children!) | 32 | + handle 'lost parent' case for recursive downloads (need to move children!) |
35 | + clean up TreeStores in main_window_file_publish on dialog close | 33 | + clean up TreeStores in main_window_file_publish on dialog close |
36 | + clean up ListStores in main_window_adv_pseudonym | 34 | + clean up ListStores in main_window_adv_pseudonym |
37 | * DATASTORE: | ||
38 | - modify testcases to not fail if database is not configured (i.e. 'mysqlcheck' DB does not exist) | ||
39 | 35 | ||
40 | 0.9.0pre3: | 36 | 0.9.0pre3: |
41 | * Determine RC bugs and fix those! | 37 | * Determine RC bugs and fix those! |
diff --git a/src/fs/fs.h b/src/fs/fs.h index 41831e8a8..699f73a79 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -1839,15 +1839,72 @@ struct GNUNET_FS_DownloadContext | |||
1839 | int tried_full_data; | 1839 | int tried_full_data; |
1840 | }; | 1840 | }; |
1841 | 1841 | ||
1842 | |||
1843 | /** | ||
1844 | * Information about an (updateable) node in the | ||
1845 | * namespace. | ||
1846 | */ | ||
1847 | struct NamespaceUpdateNode | ||
1848 | { | ||
1849 | /** | ||
1850 | * Identifier for this node. | ||
1851 | */ | ||
1852 | char *id; | ||
1853 | |||
1854 | /** | ||
1855 | * Identifier of children of this node. | ||
1856 | */ | ||
1857 | char *update; | ||
1858 | |||
1859 | /** | ||
1860 | * Metadata for this entry. | ||
1861 | */ | ||
1862 | struct GNUNET_CONTAINER_MetaData *md; | ||
1863 | |||
1864 | /** | ||
1865 | * URI of this entry in the namespace. | ||
1866 | */ | ||
1867 | struct GNUNET_FS_Uri *uri; | ||
1868 | |||
1869 | /** | ||
1870 | * Namespace update generation ID. Used to ensure | ||
1871 | * freshness of the scc_id. | ||
1872 | */ | ||
1873 | unsigned int nug; | ||
1874 | |||
1875 | /** | ||
1876 | * SCC this entry belongs to (if nug is current). | ||
1877 | */ | ||
1878 | unsigned int scc_id; | ||
1879 | |||
1880 | }; | ||
1881 | |||
1882 | |||
1842 | struct GNUNET_FS_Namespace | 1883 | struct GNUNET_FS_Namespace |
1843 | { | 1884 | { |
1844 | 1885 | ||
1845 | /** | 1886 | /** |
1887 | * Handle to the FS service context. | ||
1888 | */ | ||
1889 | struct GNUNET_FS_Handle *h; | ||
1890 | |||
1891 | /** | ||
1892 | * Array with information about nodes in the namespace. | ||
1893 | */ | ||
1894 | struct NamespaceUpdateNode **update_nodes; | ||
1895 | |||
1896 | /** | ||
1846 | * Private key for the namespace. | 1897 | * Private key for the namespace. |
1847 | */ | 1898 | */ |
1848 | struct GNUNET_CRYPTO_RsaPrivateKey *key; | 1899 | struct GNUNET_CRYPTO_RsaPrivateKey *key; |
1849 | 1900 | ||
1850 | /** | 1901 | /** |
1902 | * Hash map mapping identifiers of update nodes | ||
1903 | * to the update nodes (initialized on-demand). | ||
1904 | */ | ||
1905 | struct GNUNET_CONTAINER_MultiHashMap *update_map; | ||
1906 | |||
1907 | /** | ||
1851 | * Name of the file with the private key. | 1908 | * Name of the file with the private key. |
1852 | */ | 1909 | */ |
1853 | char *filename; | 1910 | char *filename; |
@@ -1858,9 +1915,19 @@ struct GNUNET_FS_Namespace | |||
1858 | char *name; | 1915 | char *name; |
1859 | 1916 | ||
1860 | /** | 1917 | /** |
1918 | * Size of the update nodes array. | ||
1919 | */ | ||
1920 | unsigned int update_node_count; | ||
1921 | |||
1922 | /** | ||
1861 | * Reference counter. | 1923 | * Reference counter. |
1862 | */ | 1924 | */ |
1863 | unsigned int rc; | 1925 | unsigned int rc; |
1926 | |||
1927 | /** | ||
1928 | * Generator for unique nug numbers. | ||
1929 | */ | ||
1930 | unsigned int nug_gen; | ||
1864 | }; | 1931 | }; |
1865 | 1932 | ||
1866 | 1933 | ||
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index ee3743733..a9bcaf8e5 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c | |||
@@ -59,6 +59,184 @@ get_namespace_directory (struct GNUNET_FS_Handle *h) | |||
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Return the name of the directory in which we store | ||
63 | * the update information graph for the given local namespace. | ||
64 | * | ||
65 | * @param ns namespace handle | ||
66 | * @return NULL on error, otherwise the name of the directory | ||
67 | */ | ||
68 | static char * | ||
69 | get_update_information_directory (struct GNUNET_FS_Namespace *ns) | ||
70 | { | ||
71 | char *dn; | ||
72 | char *ret; | ||
73 | |||
74 | if (GNUNET_OK != | ||
75 | GNUNET_CONFIGURATION_get_value_filename (ns->h->cfg, | ||
76 | "FS", | ||
77 | "UPDATE_DIR", | ||
78 | &dn)) | ||
79 | { | ||
80 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
81 | _("Configuration fails to specify `%s' in section `%s'\n"), | ||
82 | "UPDATE_DIR", | ||
83 | "fs"); | ||
84 | return NULL; | ||
85 | } | ||
86 | GNUNET_asprintf (&ret, | ||
87 | "%s%s%s", | ||
88 | dn, | ||
89 | DIR_SEPARATOR_STR, | ||
90 | ns->name); | ||
91 | GNUNET_free (dn); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | |||
96 | /** | ||
97 | * Write the namespace update node graph to a file. | ||
98 | * | ||
99 | * @param ns namespace to dump | ||
100 | */ | ||
101 | static void | ||
102 | write_update_information_graph (struct GNUNET_FS_Namespace *ns) | ||
103 | { | ||
104 | char * fn; | ||
105 | struct GNUNET_BIO_WriteHandle *wh; | ||
106 | unsigned int i; | ||
107 | struct NamespaceUpdateNode *n; | ||
108 | char *uris; | ||
109 | |||
110 | fn = get_update_information_directory (ns); | ||
111 | wh = GNUNET_BIO_write_open (fn); | ||
112 | if (wh == NULL) | ||
113 | { | ||
114 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
115 | _("Failed to open `%s' for writing: %s\n"), | ||
116 | STRERROR (errno)); | ||
117 | GNUNET_free (fn); | ||
118 | return; | ||
119 | } | ||
120 | if (GNUNET_OK != | ||
121 | GNUNET_BIO_write_int32 (wh, ns->update_node_count)) | ||
122 | goto END; | ||
123 | for (i=0;i<ns->update_node_count;i++) | ||
124 | { | ||
125 | n = ns->update_nodes[i]; | ||
126 | uris = GNUNET_FS_uri_to_string (n->uri); | ||
127 | if ( (GNUNET_OK != | ||
128 | GNUNET_BIO_write_string (wh, n->id)) || | ||
129 | (GNUNET_OK != | ||
130 | GNUNET_BIO_write_meta_data (wh, n->md)) || | ||
131 | (GNUNET_OK != | ||
132 | GNUNET_BIO_write_string (wh, n->update)) || | ||
133 | (GNUNET_OK != | ||
134 | GNUNET_BIO_write_string (wh, uris)) ) | ||
135 | { | ||
136 | GNUNET_free (uris); | ||
137 | break; | ||
138 | } | ||
139 | GNUNET_free (uris); | ||
140 | } | ||
141 | END: | ||
142 | if (GNUNET_OK != GNUNET_BIO_write_close (wh)) | ||
143 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
144 | _("Failed to write `%s': %s\n"), | ||
145 | STRERROR (errno)); | ||
146 | GNUNET_free (fn); | ||
147 | } | ||
148 | |||
149 | |||
150 | /** | ||
151 | * Read the namespace update node graph from a file. | ||
152 | * | ||
153 | * @param ns namespace to read | ||
154 | */ | ||
155 | static void | ||
156 | read_update_information_graph (struct GNUNET_FS_Namespace *ns) | ||
157 | { | ||
158 | char * fn; | ||
159 | struct GNUNET_BIO_ReadHandle *rh; | ||
160 | unsigned int i; | ||
161 | struct NamespaceUpdateNode *n; | ||
162 | char *uris; | ||
163 | uint32_t count; | ||
164 | char *emsg; | ||
165 | |||
166 | fn = get_update_information_directory (ns); | ||
167 | rh = GNUNET_BIO_read_open (fn); | ||
168 | if (rh == NULL) | ||
169 | { | ||
170 | GNUNET_free (fn); | ||
171 | return; | ||
172 | } | ||
173 | if (GNUNET_OK != | ||
174 | GNUNET_BIO_read_int32 (rh, &count)) | ||
175 | { | ||
176 | GNUNET_break (0); | ||
177 | goto END; | ||
178 | } | ||
179 | if (count > 1024 * 1024) | ||
180 | { | ||
181 | GNUNET_break (0); | ||
182 | goto END; | ||
183 | } | ||
184 | if (count == 0) | ||
185 | { | ||
186 | GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL)); | ||
187 | GNUNET_free (fn); | ||
188 | return; | ||
189 | } | ||
190 | ns->update_nodes = GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode*)); | ||
191 | |||
192 | for (i=0;i<count;i++) | ||
193 | { | ||
194 | n = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); | ||
195 | if ( (GNUNET_OK != | ||
196 | GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) || | ||
197 | (GNUNET_OK != | ||
198 | GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) || | ||
199 | (GNUNET_OK != | ||
200 | GNUNET_BIO_read_string (rh, "update-id", &n->update, 1024)) || | ||
201 | (GNUNET_OK != | ||
202 | GNUNET_BIO_read_string (rh, "uri", &uris, 1024 * 2)) ) | ||
203 | { | ||
204 | GNUNET_break (0); | ||
205 | GNUNET_free_non_null (n->id); | ||
206 | GNUNET_free_non_null (n->update); | ||
207 | if (n->md != NULL) | ||
208 | GNUNET_CONTAINER_meta_data_destroy (n->md); | ||
209 | GNUNET_free (n); | ||
210 | break; | ||
211 | } | ||
212 | n->uri = GNUNET_FS_uri_parse (uris, &emsg); | ||
213 | GNUNET_free (uris); | ||
214 | if (n->uri == NULL) | ||
215 | { | ||
216 | GNUNET_break (0); | ||
217 | GNUNET_free (emsg); | ||
218 | GNUNET_free (n->id); | ||
219 | GNUNET_free (n->update); | ||
220 | GNUNET_CONTAINER_meta_data_destroy (n->md); | ||
221 | GNUNET_free (n); | ||
222 | break; | ||
223 | } | ||
224 | ns->update_nodes[i] = n; | ||
225 | } | ||
226 | ns->update_node_count = i; | ||
227 | END: | ||
228 | if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) | ||
229 | { | ||
230 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
231 | _("Failed to write `%s': %s\n"), | ||
232 | emsg); | ||
233 | GNUNET_free (emsg); | ||
234 | } | ||
235 | GNUNET_free (fn); | ||
236 | } | ||
237 | |||
238 | |||
239 | /** | ||
62 | * Context for advertising a namespace. | 240 | * Context for advertising a namespace. |
63 | */ | 241 | */ |
64 | struct AdvertisementContext | 242 | struct AdvertisementContext |
@@ -363,6 +541,7 @@ GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, | |||
363 | name); | 541 | name); |
364 | GNUNET_free (dn); | 542 | GNUNET_free (dn); |
365 | ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace)); | 543 | ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace)); |
544 | ret->h = h; | ||
366 | ret->rc = 1; | 545 | ret->rc = 1; |
367 | ret->key = GNUNET_CRYPTO_rsa_key_create_from_file (fn); | 546 | ret->key = GNUNET_CRYPTO_rsa_key_create_from_file (fn); |
368 | if (ret->key == NULL) | 547 | if (ret->key == NULL) |
@@ -395,6 +574,9 @@ int | |||
395 | GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, | 574 | GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, |
396 | int freeze) | 575 | int freeze) |
397 | { | 576 | { |
577 | unsigned int i; | ||
578 | struct NamespaceUpdateNode *nsn; | ||
579 | |||
398 | namespace->rc--; | 580 | namespace->rc--; |
399 | if (freeze) | 581 | if (freeze) |
400 | { | 582 | { |
@@ -408,6 +590,20 @@ GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, | |||
408 | GNUNET_CRYPTO_rsa_key_free (namespace->key); | 590 | GNUNET_CRYPTO_rsa_key_free (namespace->key); |
409 | GNUNET_free (namespace->filename); | 591 | GNUNET_free (namespace->filename); |
410 | GNUNET_free (namespace->name); | 592 | GNUNET_free (namespace->name); |
593 | for (i=0;i<namespace->update_node_count;i++) | ||
594 | { | ||
595 | nsn = namespace->update_nodes[i]; | ||
596 | GNUNET_CONTAINER_meta_data_destroy (nsn->md); | ||
597 | GNUNET_FS_uri_destroy (nsn->uri); | ||
598 | GNUNET_free (nsn->id); | ||
599 | GNUNET_free (nsn->update); | ||
600 | GNUNET_free (nsn); | ||
601 | } | ||
602 | GNUNET_array_grow (namespace->update_nodes, | ||
603 | namespace->update_node_count, | ||
604 | 0); | ||
605 | if (namespace->update_map != NULL) | ||
606 | GNUNET_CONTAINER_multihashmap_destroy (namespace->update_map); | ||
411 | GNUNET_free (namespace); | 607 | GNUNET_free (namespace); |
412 | } | 608 | } |
413 | return GNUNET_OK; | 609 | return GNUNET_OK; |
@@ -507,22 +703,550 @@ GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h, | |||
507 | 703 | ||
508 | 704 | ||
509 | 705 | ||
706 | |||
510 | /** | 707 | /** |
511 | * List all of the identifiers in the namespace for | 708 | * Context for the SKS publication. |
512 | * which we could produce an update. | 709 | */ |
710 | struct PublishSksContext | ||
711 | { | ||
712 | |||
713 | /** | ||
714 | * URI of the new entry in the namespace. | ||
715 | */ | ||
716 | struct GNUNET_FS_Uri *uri; | ||
717 | |||
718 | /** | ||
719 | * Namespace update node to add to namespace on success (or to be | ||
720 | * deleted if publishing failed). | ||
721 | */ | ||
722 | struct NamespaceUpdateNode *nsn; | ||
723 | |||
724 | /** | ||
725 | * Namespace we're publishing to. | ||
726 | */ | ||
727 | struct GNUNET_FS_Namespace *namespace; | ||
728 | |||
729 | /** | ||
730 | * Handle to the datastore. | ||
731 | */ | ||
732 | struct GNUNET_DATASTORE_Handle *dsh; | ||
733 | |||
734 | /** | ||
735 | * Function to call once we're done. | ||
736 | */ | ||
737 | GNUNET_FS_PublishContinuation cont; | ||
738 | |||
739 | /** | ||
740 | * Closure for cont. | ||
741 | */ | ||
742 | void *cont_cls; | ||
743 | |||
744 | }; | ||
745 | |||
746 | |||
747 | /** | ||
748 | * Function called by the datastore API with | ||
749 | * the result from the PUT (SBlock) request. | ||
750 | * | ||
751 | * @param cls closure of type "struct PublishSksContext*" | ||
752 | * @param success GNUNET_OK on success | ||
753 | * @param msg error message (or NULL) | ||
754 | */ | ||
755 | static void | ||
756 | sb_put_cont (void *cls, | ||
757 | int success, | ||
758 | const char *msg) | ||
759 | { | ||
760 | struct PublishSksContext *psc = cls; | ||
761 | GNUNET_HashCode hc; | ||
762 | |||
763 | if (NULL != psc->dsh) | ||
764 | { | ||
765 | GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); | ||
766 | psc->dsh = NULL; | ||
767 | } | ||
768 | if (GNUNET_OK != success) | ||
769 | { | ||
770 | psc->cont (psc->cont_cls, | ||
771 | NULL, | ||
772 | msg); | ||
773 | } | ||
774 | else | ||
775 | { | ||
776 | if (psc->nsn != NULL) | ||
777 | { | ||
778 | /* FIXME: this can be done much more | ||
779 | efficiently by simply appending to the | ||
780 | file and overwriting the 4-byte header */ | ||
781 | if (psc->namespace->update_nodes == NULL) | ||
782 | read_update_information_graph (psc->namespace); | ||
783 | GNUNET_array_append (psc->namespace->update_nodes, | ||
784 | psc->namespace->update_node_count, | ||
785 | psc->nsn); | ||
786 | if (psc->namespace->update_map != NULL) | ||
787 | { | ||
788 | GNUNET_CRYPTO_hash (psc->nsn->id, | ||
789 | strlen (psc->nsn->id), | ||
790 | &hc); | ||
791 | GNUNET_CONTAINER_multihashmap_put (psc->namespace->update_map, | ||
792 | &hc, | ||
793 | psc->nsn, | ||
794 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
795 | } | ||
796 | psc->nsn = NULL; | ||
797 | write_update_information_graph (psc->namespace); | ||
798 | } | ||
799 | psc->cont (psc->cont_cls, | ||
800 | psc->uri, | ||
801 | NULL); | ||
802 | } | ||
803 | GNUNET_FS_namespace_delete (psc->namespace, | ||
804 | GNUNET_NO); | ||
805 | GNUNET_FS_uri_destroy (psc->uri); | ||
806 | if (psc->nsn != NULL) | ||
807 | { | ||
808 | GNUNET_CONTAINER_meta_data_destroy (psc->nsn->md); | ||
809 | GNUNET_FS_uri_destroy (psc->nsn->uri); | ||
810 | GNUNET_free (psc->nsn->id); | ||
811 | GNUNET_free (psc->nsn->update); | ||
812 | GNUNET_free (psc->nsn); | ||
813 | } | ||
814 | GNUNET_free (psc); | ||
815 | } | ||
816 | |||
817 | |||
818 | /** | ||
819 | * Publish an SBlock on GNUnet. | ||
820 | * | ||
821 | * @param h handle to the file sharing subsystem | ||
822 | * @param namespace namespace to publish in | ||
823 | * @param identifier identifier to use | ||
824 | * @param update update identifier to use | ||
825 | * @param meta metadata to use | ||
826 | * @param uri URI to refer to in the SBlock | ||
827 | * @param expirationTime when the SBlock expires | ||
828 | * @param anonymity anonymity level for the SBlock | ||
829 | * @param priority priority for the SBlock | ||
830 | * @param options publication options | ||
831 | * @param cont continuation | ||
832 | * @param cont_cls closure for cont | ||
833 | */ | ||
834 | void | ||
835 | GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | ||
836 | struct GNUNET_FS_Namespace *namespace, | ||
837 | const char *identifier, | ||
838 | const char *update, | ||
839 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
840 | const struct GNUNET_FS_Uri *uri, | ||
841 | struct GNUNET_TIME_Absolute expirationTime, | ||
842 | uint32_t anonymity, | ||
843 | uint32_t priority, | ||
844 | enum GNUNET_FS_PublishOptions options, | ||
845 | GNUNET_FS_PublishContinuation cont, | ||
846 | void *cont_cls) | ||
847 | { | ||
848 | struct PublishSksContext *psc; | ||
849 | struct GNUNET_CRYPTO_AesSessionKey sk; | ||
850 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
851 | struct GNUNET_FS_Uri *sks_uri; | ||
852 | char *uris; | ||
853 | size_t size; | ||
854 | size_t slen; | ||
855 | size_t nidlen; | ||
856 | size_t idlen; | ||
857 | ssize_t mdsize; | ||
858 | struct SBlock *sb; | ||
859 | struct SBlock *sb_enc; | ||
860 | char *dest; | ||
861 | struct GNUNET_CONTAINER_MetaData *mmeta; | ||
862 | GNUNET_HashCode key; /* hash of thisId = key */ | ||
863 | GNUNET_HashCode id; /* hash of hc = identifier */ | ||
864 | GNUNET_HashCode query; /* id ^ nsid = DB query */ | ||
865 | |||
866 | if (NULL == meta) | ||
867 | mmeta = GNUNET_CONTAINER_meta_data_create (); | ||
868 | else | ||
869 | mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta); | ||
870 | uris = GNUNET_FS_uri_to_string (uri); | ||
871 | slen = strlen (uris) + 1; | ||
872 | idlen = strlen (identifier); | ||
873 | if (update == NULL) | ||
874 | update = ""; | ||
875 | nidlen = strlen (update) + 1; | ||
876 | mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta); | ||
877 | size = sizeof (struct SBlock) + slen + nidlen + mdsize; | ||
878 | if (size > MAX_SBLOCK_SIZE) | ||
879 | { | ||
880 | size = MAX_SBLOCK_SIZE; | ||
881 | mdsize = size - (sizeof (struct SBlock) + slen + nidlen); | ||
882 | } | ||
883 | sb = GNUNET_malloc (sizeof (struct SBlock) + size); | ||
884 | dest = (char *) &sb[1]; | ||
885 | memcpy (dest, update, nidlen); | ||
886 | dest += nidlen; | ||
887 | memcpy (dest, uris, slen); | ||
888 | GNUNET_free (uris); | ||
889 | dest += slen; | ||
890 | mdsize = GNUNET_CONTAINER_meta_data_serialize (mmeta, | ||
891 | &dest, | ||
892 | mdsize, | ||
893 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
894 | GNUNET_CONTAINER_meta_data_destroy (mmeta); | ||
895 | if (mdsize == -1) | ||
896 | { | ||
897 | GNUNET_break (0); | ||
898 | GNUNET_free (sb); | ||
899 | cont (cont_cls, | ||
900 | NULL, | ||
901 | _("Internal error.")); | ||
902 | return; | ||
903 | } | ||
904 | size = sizeof (struct SBlock) + mdsize + slen + nidlen; | ||
905 | sb_enc = GNUNET_malloc (size); | ||
906 | GNUNET_CRYPTO_hash (identifier, idlen, &key); | ||
907 | GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &id); | ||
908 | sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); | ||
909 | sks_uri->type = sks; | ||
910 | GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &sb_enc->subspace); | ||
911 | GNUNET_CRYPTO_hash (&sb_enc->subspace, | ||
912 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
913 | &sks_uri->data.sks.namespace); | ||
914 | sks_uri->data.sks.identifier = GNUNET_strdup (identifier); | ||
915 | GNUNET_CRYPTO_hash_xor (&id, | ||
916 | &sks_uri->data.sks.namespace, | ||
917 | &sb_enc->identifier); | ||
918 | GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv); | ||
919 | GNUNET_CRYPTO_aes_encrypt (&sb[1], | ||
920 | size - sizeof (struct SBlock), | ||
921 | &sk, | ||
922 | &iv, | ||
923 | &sb_enc[1]); | ||
924 | sb_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK); | ||
925 | sb_enc->purpose.size = htonl(slen + mdsize + nidlen | ||
926 | + sizeof(struct SBlock) | ||
927 | - sizeof(struct GNUNET_CRYPTO_RsaSignature)); | ||
928 | GNUNET_assert (GNUNET_OK == | ||
929 | GNUNET_CRYPTO_rsa_sign (namespace->key, | ||
930 | &sb_enc->purpose, | ||
931 | &sb_enc->signature)); | ||
932 | psc = GNUNET_malloc (sizeof(struct PublishSksContext)); | ||
933 | psc->uri = sks_uri; | ||
934 | psc->cont = cont; | ||
935 | psc->namespace = namespace; | ||
936 | namespace->rc++; | ||
937 | psc->cont_cls = cont_cls; | ||
938 | if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | ||
939 | { | ||
940 | GNUNET_free (sb_enc); | ||
941 | GNUNET_free (sb); | ||
942 | sb_put_cont (psc, | ||
943 | GNUNET_OK, | ||
944 | NULL); | ||
945 | return; | ||
946 | } | ||
947 | psc->dsh = GNUNET_DATASTORE_connect (h->cfg, h->sched); | ||
948 | if (NULL == psc->dsh) | ||
949 | { | ||
950 | GNUNET_free (sb_enc); | ||
951 | GNUNET_free (sb); | ||
952 | sb_put_cont (psc, | ||
953 | GNUNET_NO, | ||
954 | _("Failed to connect to datastore.")); | ||
955 | return; | ||
956 | } | ||
957 | GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, | ||
958 | &id, | ||
959 | &query); | ||
960 | if (NULL != update) | ||
961 | { | ||
962 | psc->nsn = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); | ||
963 | psc->nsn->id = GNUNET_strdup (identifier); | ||
964 | psc->nsn->update = GNUNET_strdup (update); | ||
965 | psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); | ||
966 | psc->nsn->uri = GNUNET_FS_uri_dup (uri); | ||
967 | } | ||
968 | GNUNET_DATASTORE_put (psc->dsh, | ||
969 | 0, | ||
970 | &sb_enc->identifier, | ||
971 | size, | ||
972 | sb_enc, | ||
973 | GNUNET_BLOCK_TYPE_SBLOCK, | ||
974 | priority, | ||
975 | anonymity, | ||
976 | expirationTime, | ||
977 | -2, 1, | ||
978 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
979 | &sb_put_cont, | ||
980 | psc); | ||
981 | GNUNET_free (sb); | ||
982 | GNUNET_free (sb_enc); | ||
983 | } | ||
984 | |||
985 | |||
986 | /** | ||
987 | * Closure for 'process_update_node'. | ||
988 | */ | ||
989 | struct ProcessUpdateClosure | ||
990 | { | ||
991 | /** | ||
992 | * Function to call for each node. | ||
993 | */ | ||
994 | GNUNET_FS_IdentifierProcessor ip; | ||
995 | |||
996 | /** | ||
997 | * Closure for 'ip'. | ||
998 | */ | ||
999 | void *ip_cls; | ||
1000 | }; | ||
1001 | |||
1002 | |||
1003 | /** | ||
1004 | * Call the iterator in the closure for each node. | ||
1005 | * | ||
1006 | * @param cls closure (of type 'struct ProcessUpdateClosure *') | ||
1007 | * @param key current key code | ||
1008 | * @param value value in the hash map (of type 'struct NamespaceUpdateNode *') | ||
1009 | * @return GNUNET_YES if we should continue to | ||
1010 | * iterate, | ||
1011 | * GNUNET_NO if not. | ||
1012 | */ | ||
1013 | static int | ||
1014 | process_update_node (void *cls, | ||
1015 | const GNUNET_HashCode * key, | ||
1016 | void *value) | ||
1017 | { | ||
1018 | struct ProcessUpdateClosure *pc = cls; | ||
1019 | struct NamespaceUpdateNode *nsn = value; | ||
1020 | |||
1021 | pc->ip (pc->ip_cls, | ||
1022 | nsn->id, | ||
1023 | nsn->uri, | ||
1024 | nsn->md, | ||
1025 | nsn->update); | ||
1026 | return GNUNET_YES; | ||
1027 | } | ||
1028 | |||
1029 | |||
1030 | /** | ||
1031 | * Closure for 'find_sccs'. | ||
1032 | */ | ||
1033 | struct FindSccClosure | ||
1034 | { | ||
1035 | /** | ||
1036 | * Namespace we are operating on. | ||
1037 | */ | ||
1038 | struct GNUNET_FS_Namespace *namespace; | ||
1039 | |||
1040 | /** | ||
1041 | * Array with 'head's of SCCs. | ||
1042 | */ | ||
1043 | struct NamespaceUpdateNode **scc_array; | ||
1044 | |||
1045 | /** | ||
1046 | * Size of 'scc_array' | ||
1047 | */ | ||
1048 | unsigned int scc_array_size; | ||
1049 | |||
1050 | /** | ||
1051 | * Current generational ID used. | ||
1052 | */ | ||
1053 | unsigned int nug; | ||
1054 | |||
1055 | /** | ||
1056 | * Identifier for the current SCC, or UINT_MAX for none yet. | ||
1057 | */ | ||
1058 | unsigned int id; | ||
1059 | }; | ||
1060 | |||
1061 | |||
1062 | /** | ||
1063 | * Find all nodes reachable from the current node (including the | ||
1064 | * current node itself). If they are in no SCC, add them to the | ||
1065 | * current one. If they are the head of another SCC, merge the | ||
1066 | * SCCs. If they are in the middle of another SCC, let them be. | ||
1067 | * We can tell that a node is already in an SCC by checking if | ||
1068 | * its 'nug' field is set to the current 'nug' value. It is the | ||
1069 | * head of an SCC if it is in the 'scc_array' under its respective | ||
1070 | * 'scc_id'. | ||
1071 | * | ||
1072 | * @param cls closure (of type 'struct FindSccClosure') | ||
1073 | * @param key current key code | ||
1074 | * @param value value in the hash map | ||
1075 | * @return GNUNET_YES if we should continue to | ||
1076 | * iterate, | ||
1077 | * GNUNET_NO if not. | ||
1078 | */ | ||
1079 | static int | ||
1080 | find_sccs (void *cls, | ||
1081 | const GNUNET_HashCode * key, | ||
1082 | void *value) | ||
1083 | { | ||
1084 | struct FindSccClosure *fc = cls; | ||
1085 | struct NamespaceUpdateNode *nsn = value; | ||
1086 | GNUNET_HashCode hc; | ||
1087 | |||
1088 | if (nsn->nug == fc->nug) | ||
1089 | { | ||
1090 | if (fc->scc_array[nsn->scc_id] != nsn) | ||
1091 | return GNUNET_YES; /* part of another SCC, end trace */ | ||
1092 | fc->scc_array[nsn->scc_id] = NULL; | ||
1093 | if (fc->id == UINT_MAX) | ||
1094 | fc->id = nsn->scc_id; /* take over ID */ | ||
1095 | } | ||
1096 | else | ||
1097 | { | ||
1098 | nsn->nug = fc->nug; | ||
1099 | /* trace */ | ||
1100 | GNUNET_CRYPTO_hash (nsn->update, | ||
1101 | strlen (nsn->update), | ||
1102 | &hc); | ||
1103 | GNUNET_CONTAINER_multihashmap_get_multiple (fc->namespace->update_map, | ||
1104 | &hc, | ||
1105 | &find_sccs, | ||
1106 | fc); | ||
1107 | } | ||
1108 | return GNUNET_YES; | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | /** | ||
1113 | * List all of the identifiers in the namespace for which we could | ||
1114 | * produce an update. Namespace updates form a graph where each node | ||
1115 | * has a name. Each node can have any number of URI/meta-data entries | ||
1116 | * which can each be linked to other nodes. Cycles are possible. | ||
1117 | * | ||
1118 | * Calling this function with "next_id" NULL will cause the library to | ||
1119 | * call "ip" with a root for each strongly connected component of the | ||
1120 | * graph (a root being a node from which all other nodes in the Scc | ||
1121 | * are reachable). | ||
1122 | * | ||
1123 | * Calling this function with "next_id" being the name of a node will | ||
1124 | * cause the library to call "ip" with all children of the node. Note | ||
1125 | * that cycles within an SCC are possible (including self-loops). | ||
513 | * | 1126 | * |
514 | * @param namespace namespace to inspect for updateable content | 1127 | * @param namespace namespace to inspect for updateable content |
1128 | * @param next_id ID to look for; use NULL to look for SCC roots | ||
515 | * @param ip function to call on each updateable identifier | 1129 | * @param ip function to call on each updateable identifier |
516 | * @param ip_cls closure for ip | 1130 | * @param ip_cls closure for ip |
517 | */ | 1131 | */ |
518 | void | 1132 | void |
519 | GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | 1133 | GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, |
1134 | const char *next_id, | ||
520 | GNUNET_FS_IdentifierProcessor ip, | 1135 | GNUNET_FS_IdentifierProcessor ip, |
521 | void *ip_cls) | 1136 | void *ip_cls) |
522 | { | 1137 | { |
523 | GNUNET_break (0); | 1138 | unsigned int i; |
524 | } | 1139 | unsigned int nug; |
1140 | GNUNET_HashCode hc; | ||
1141 | struct NamespaceUpdateNode *nsn; | ||
1142 | struct ProcessUpdateClosure pc; | ||
1143 | struct FindSccClosure fc; | ||
525 | 1144 | ||
1145 | if (namespace->update_nodes == NULL) | ||
1146 | read_update_information_graph (namespace); | ||
1147 | if (namespace->update_nodes == NULL) | ||
1148 | return; /* no nodes */ | ||
1149 | if (namespace->update_map == NULL) | ||
1150 | { | ||
1151 | /* need to construct */ | ||
1152 | namespace->update_map = GNUNET_CONTAINER_multihashmap_create (2 + 3 * namespace->update_node_count / 4); | ||
1153 | for (i=0;i<namespace->update_node_count;i++) | ||
1154 | { | ||
1155 | nsn = namespace->update_nodes[i]; | ||
1156 | GNUNET_CRYPTO_hash (nsn->id, | ||
1157 | strlen (nsn->id), | ||
1158 | &hc); | ||
1159 | GNUNET_CONTAINER_multihashmap_put (namespace->update_map, | ||
1160 | &hc, | ||
1161 | nsn, | ||
1162 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1163 | } | ||
1164 | } | ||
1165 | if (next_id != NULL) | ||
1166 | { | ||
1167 | GNUNET_CRYPTO_hash (next_id, | ||
1168 | strlen (next_id), | ||
1169 | &hc); | ||
1170 | pc.ip = ip; | ||
1171 | pc.ip_cls = ip_cls; | ||
1172 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, | ||
1173 | &hc, | ||
1174 | &process_update_node, | ||
1175 | &pc); | ||
1176 | return; | ||
1177 | } | ||
1178 | /* Find heads of SCCs in update graph */ | ||
1179 | nug = ++namespace->nug_gen; | ||
1180 | fc.scc_array = NULL; | ||
1181 | fc.scc_array_size = 0; | ||
1182 | |||
1183 | for (i=0;i<namespace->update_node_count;i++) | ||
1184 | { | ||
1185 | nsn = namespace->update_nodes[i]; | ||
1186 | if (nsn->nug == nug) | ||
1187 | continue; /* already placed in SCC */ | ||
1188 | GNUNET_CRYPTO_hash (nsn->update, | ||
1189 | strlen (nsn->update), | ||
1190 | &hc); | ||
1191 | nsn->nug = nug; | ||
1192 | fc.id = UINT_MAX; | ||
1193 | fc.nug = nug; | ||
1194 | fc.namespace = namespace; | ||
1195 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, | ||
1196 | &hc, | ||
1197 | &find_sccs, | ||
1198 | &fc); | ||
1199 | if (fc.id == UINT_MAX) | ||
1200 | { | ||
1201 | /* start new SCC */ | ||
1202 | for (fc.id=0;fc.id<fc.scc_array_size;fc.id++) | ||
1203 | { | ||
1204 | if (fc.scc_array[fc.id] == NULL) | ||
1205 | { | ||
1206 | fc.scc_array[fc.id] = nsn; | ||
1207 | nsn->scc_id = fc.id; | ||
1208 | break; | ||
1209 | } | ||
1210 | } | ||
1211 | if (fc.id == fc.scc_array_size) | ||
1212 | { | ||
1213 | GNUNET_array_append (fc.scc_array, | ||
1214 | fc.scc_array_size, | ||
1215 | nsn); | ||
1216 | nsn->scc_id = fc.id; | ||
1217 | } | ||
1218 | /* put all nodes with same identifier into this SCC */ | ||
1219 | GNUNET_CRYPTO_hash (nsn->id, | ||
1220 | strlen (nsn->id), | ||
1221 | &hc); | ||
1222 | fc.id = nsn->scc_id; | ||
1223 | fc.nug = nug; | ||
1224 | fc.namespace = namespace; | ||
1225 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, | ||
1226 | &hc, | ||
1227 | &find_sccs, | ||
1228 | &fc); | ||
1229 | } | ||
1230 | else | ||
1231 | { | ||
1232 | /* make head of SCC "id" */ | ||
1233 | fc.scc_array[fc.id] = nsn; | ||
1234 | nsn->scc_id = fc.id; | ||
1235 | } | ||
1236 | } | ||
1237 | for (i=0;i<fc.scc_array_size;i++) | ||
1238 | { | ||
1239 | nsn = fc.scc_array[i]; | ||
1240 | ip (ip_cls, | ||
1241 | nsn->id, | ||
1242 | nsn->uri, | ||
1243 | nsn->md, | ||
1244 | nsn->update); | ||
1245 | } | ||
1246 | GNUNET_array_grow (fc.scc_array, | ||
1247 | fc.scc_array_size, | ||
1248 | 0); | ||
1249 | } | ||
526 | 1250 | ||
527 | 1251 | ||
528 | /* end of fs_namespace.c */ | 1252 | /* end of fs_namespace.c */ |
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 73fc710e1..2c9d41b05 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c | |||
@@ -1709,223 +1709,4 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, | |||
1709 | } | 1709 | } |
1710 | 1710 | ||
1711 | 1711 | ||
1712 | /** | ||
1713 | * Context for the SKS publication. | ||
1714 | */ | ||
1715 | struct PublishSksContext | ||
1716 | { | ||
1717 | |||
1718 | /** | ||
1719 | * Global FS context. | ||
1720 | */ | ||
1721 | struct GNUNET_FS_Uri *uri; | ||
1722 | |||
1723 | /** | ||
1724 | * Handle to the datastore. | ||
1725 | */ | ||
1726 | struct GNUNET_DATASTORE_Handle *dsh; | ||
1727 | |||
1728 | /** | ||
1729 | * Function to call once we're done. | ||
1730 | */ | ||
1731 | GNUNET_FS_PublishContinuation cont; | ||
1732 | |||
1733 | /** | ||
1734 | * Closure for cont. | ||
1735 | */ | ||
1736 | void *cont_cls; | ||
1737 | |||
1738 | }; | ||
1739 | |||
1740 | |||
1741 | /** | ||
1742 | * Function called by the datastore API with | ||
1743 | * the result from the PUT (SBlock) request. | ||
1744 | * | ||
1745 | * @param cls closure of type "struct PublishSksContext*" | ||
1746 | * @param success GNUNET_OK on success | ||
1747 | * @param msg error message (or NULL) | ||
1748 | */ | ||
1749 | static void | ||
1750 | sb_put_cont (void *cls, | ||
1751 | int success, | ||
1752 | const char *msg) | ||
1753 | { | ||
1754 | struct PublishSksContext *psc = cls; | ||
1755 | |||
1756 | if (NULL != psc->dsh) | ||
1757 | { | ||
1758 | GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); | ||
1759 | psc->dsh = NULL; | ||
1760 | } | ||
1761 | if (GNUNET_OK != success) | ||
1762 | psc->cont (psc->cont_cls, | ||
1763 | NULL, | ||
1764 | msg); | ||
1765 | else | ||
1766 | psc->cont (psc->cont_cls, | ||
1767 | psc->uri, | ||
1768 | NULL); | ||
1769 | GNUNET_FS_uri_destroy (psc->uri); | ||
1770 | GNUNET_free (psc); | ||
1771 | } | ||
1772 | |||
1773 | |||
1774 | /** | ||
1775 | * Publish an SBlock on GNUnet. | ||
1776 | * | ||
1777 | * @param h handle to the file sharing subsystem | ||
1778 | * @param namespace namespace to publish in | ||
1779 | * @param identifier identifier to use | ||
1780 | * @param update update identifier to use | ||
1781 | * @param meta metadata to use | ||
1782 | * @param uri URI to refer to in the SBlock | ||
1783 | * @param expirationTime when the SBlock expires | ||
1784 | * @param anonymity anonymity level for the SBlock | ||
1785 | * @param priority priority for the SBlock | ||
1786 | * @param options publication options | ||
1787 | * @param cont continuation | ||
1788 | * @param cont_cls closure for cont | ||
1789 | */ | ||
1790 | void | ||
1791 | GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | ||
1792 | struct GNUNET_FS_Namespace *namespace, | ||
1793 | const char *identifier, | ||
1794 | const char *update, | ||
1795 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
1796 | const struct GNUNET_FS_Uri *uri, | ||
1797 | struct GNUNET_TIME_Absolute expirationTime, | ||
1798 | uint32_t anonymity, | ||
1799 | uint32_t priority, | ||
1800 | enum GNUNET_FS_PublishOptions options, | ||
1801 | GNUNET_FS_PublishContinuation cont, | ||
1802 | void *cont_cls) | ||
1803 | { | ||
1804 | struct PublishSksContext *psc; | ||
1805 | struct GNUNET_CRYPTO_AesSessionKey sk; | ||
1806 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
1807 | struct GNUNET_FS_Uri *sks_uri; | ||
1808 | char *uris; | ||
1809 | size_t size; | ||
1810 | size_t slen; | ||
1811 | size_t nidlen; | ||
1812 | size_t idlen; | ||
1813 | ssize_t mdsize; | ||
1814 | struct SBlock *sb; | ||
1815 | struct SBlock *sb_enc; | ||
1816 | char *dest; | ||
1817 | struct GNUNET_CONTAINER_MetaData *mmeta; | ||
1818 | GNUNET_HashCode key; /* hash of thisId = key */ | ||
1819 | GNUNET_HashCode id; /* hash of hc = identifier */ | ||
1820 | GNUNET_HashCode query; /* id ^ nsid = DB query */ | ||
1821 | |||
1822 | if (NULL == meta) | ||
1823 | mmeta = GNUNET_CONTAINER_meta_data_create (); | ||
1824 | else | ||
1825 | mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta); | ||
1826 | uris = GNUNET_FS_uri_to_string (uri); | ||
1827 | slen = strlen (uris) + 1; | ||
1828 | idlen = strlen (identifier); | ||
1829 | if (update == NULL) | ||
1830 | update = ""; | ||
1831 | nidlen = strlen (update) + 1; | ||
1832 | mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta); | ||
1833 | size = sizeof (struct SBlock) + slen + nidlen + mdsize; | ||
1834 | if (size > MAX_SBLOCK_SIZE) | ||
1835 | { | ||
1836 | size = MAX_SBLOCK_SIZE; | ||
1837 | mdsize = size - (sizeof (struct SBlock) + slen + nidlen); | ||
1838 | } | ||
1839 | sb = GNUNET_malloc (sizeof (struct SBlock) + size); | ||
1840 | dest = (char *) &sb[1]; | ||
1841 | memcpy (dest, update, nidlen); | ||
1842 | dest += nidlen; | ||
1843 | memcpy (dest, uris, slen); | ||
1844 | GNUNET_free (uris); | ||
1845 | dest += slen; | ||
1846 | mdsize = GNUNET_CONTAINER_meta_data_serialize (mmeta, | ||
1847 | &dest, | ||
1848 | mdsize, | ||
1849 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
1850 | GNUNET_CONTAINER_meta_data_destroy (mmeta); | ||
1851 | if (mdsize == -1) | ||
1852 | { | ||
1853 | GNUNET_break (0); | ||
1854 | GNUNET_free (sb); | ||
1855 | cont (cont_cls, | ||
1856 | NULL, | ||
1857 | _("Internal error.")); | ||
1858 | return; | ||
1859 | } | ||
1860 | size = sizeof (struct SBlock) + mdsize + slen + nidlen; | ||
1861 | sb_enc = GNUNET_malloc (size); | ||
1862 | GNUNET_CRYPTO_hash (identifier, idlen, &key); | ||
1863 | GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &id); | ||
1864 | sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); | ||
1865 | sks_uri->type = sks; | ||
1866 | GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &sb_enc->subspace); | ||
1867 | GNUNET_CRYPTO_hash (&sb_enc->subspace, | ||
1868 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
1869 | &sks_uri->data.sks.namespace); | ||
1870 | sks_uri->data.sks.identifier = GNUNET_strdup (identifier); | ||
1871 | GNUNET_CRYPTO_hash_xor (&id, | ||
1872 | &sks_uri->data.sks.namespace, | ||
1873 | &sb_enc->identifier); | ||
1874 | GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv); | ||
1875 | GNUNET_CRYPTO_aes_encrypt (&sb[1], | ||
1876 | size - sizeof (struct SBlock), | ||
1877 | &sk, | ||
1878 | &iv, | ||
1879 | &sb_enc[1]); | ||
1880 | sb_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK); | ||
1881 | sb_enc->purpose.size = htonl(slen + mdsize + nidlen | ||
1882 | + sizeof(struct SBlock) | ||
1883 | - sizeof(struct GNUNET_CRYPTO_RsaSignature)); | ||
1884 | GNUNET_assert (GNUNET_OK == | ||
1885 | GNUNET_CRYPTO_rsa_sign (namespace->key, | ||
1886 | &sb_enc->purpose, | ||
1887 | &sb_enc->signature)); | ||
1888 | psc = GNUNET_malloc (sizeof(struct PublishSksContext)); | ||
1889 | psc->uri = sks_uri; | ||
1890 | psc->cont = cont; | ||
1891 | psc->cont_cls = cont_cls; | ||
1892 | if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | ||
1893 | { | ||
1894 | GNUNET_free (sb_enc); | ||
1895 | GNUNET_free (sb); | ||
1896 | sb_put_cont (psc, | ||
1897 | GNUNET_OK, | ||
1898 | NULL); | ||
1899 | return; | ||
1900 | } | ||
1901 | psc->dsh = GNUNET_DATASTORE_connect (h->cfg, h->sched); | ||
1902 | if (NULL == psc->dsh) | ||
1903 | { | ||
1904 | GNUNET_free (sb_enc); | ||
1905 | GNUNET_free (sb); | ||
1906 | sb_put_cont (psc, | ||
1907 | GNUNET_NO, | ||
1908 | _("Failed to connect to datastore.")); | ||
1909 | return; | ||
1910 | } | ||
1911 | GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, | ||
1912 | &id, | ||
1913 | &query); | ||
1914 | GNUNET_DATASTORE_put (psc->dsh, | ||
1915 | 0, | ||
1916 | &sb_enc->identifier, | ||
1917 | size, | ||
1918 | sb_enc, | ||
1919 | GNUNET_BLOCK_TYPE_SBLOCK, | ||
1920 | priority, | ||
1921 | anonymity, | ||
1922 | expirationTime, | ||
1923 | -2, 1, | ||
1924 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
1925 | &sb_put_cont, | ||
1926 | psc); | ||
1927 | GNUNET_free (sb); | ||
1928 | GNUNET_free (sb_enc); | ||
1929 | } | ||
1930 | |||
1931 | /* end of fs_publish.c */ | 1712 | /* end of fs_publish.c */ |