diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-18 19:03:26 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-18 19:03:26 +0000 |
commit | c456c5bb7f9b95d1800ad6e2892a77f40a08493e (patch) | |
tree | 8b04e75f8a65225848816d8e588b28413ff9d758 /src/fs | |
parent | 6d0a62078edfa5c0001acb93d517c674c5124f4e (diff) | |
download | gnunet-c456c5bb7f9b95d1800ad6e2892a77f40a08493e.tar.gz gnunet-c456c5bb7f9b95d1800ad6e2892a77f40a08493e.zip |
make all (?) asynchronously operating FS operations actually cancel-able
Diffstat (limited to 'src/fs')
-rw-r--r-- | src/fs/Makefile.am | 2 | ||||
-rw-r--r-- | src/fs/fs_api.h | 23 | ||||
-rw-r--r-- | src/fs/fs_list_indexed.c | 65 | ||||
-rw-r--r-- | src/fs/fs_namespace.c | 439 | ||||
-rw-r--r-- | src/fs/fs_namespace_advertise.c | 323 | ||||
-rw-r--r-- | src/fs/fs_publish.c | 397 | ||||
-rw-r--r-- | src/fs/fs_publish_ksk.c | 342 | ||||
-rw-r--r-- | src/fs/fs_tree.c | 3 | ||||
-rw-r--r-- | src/fs/gnunet-fs.c | 28 | ||||
-rw-r--r-- | src/fs/gnunet-publish.c | 2 |
10 files changed, 854 insertions, 770 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index c4db16fb0..d9b0fbadd 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am | |||
@@ -33,8 +33,10 @@ libgnunetfs_la_SOURCES = \ | |||
33 | fs_getopt.c \ | 33 | fs_getopt.c \ |
34 | fs_list_indexed.c \ | 34 | fs_list_indexed.c \ |
35 | fs_publish.c \ | 35 | fs_publish.c \ |
36 | fs_publish_ksk.c \ | ||
36 | fs_misc.c \ | 37 | fs_misc.c \ |
37 | fs_namespace.c \ | 38 | fs_namespace.c \ |
39 | fs_namespace_advertise.c \ | ||
38 | fs_search.c \ | 40 | fs_search.c \ |
39 | fs_sharetree.c \ | 41 | fs_sharetree.c \ |
40 | fs_tree.c fs_tree.h \ | 42 | fs_tree.c fs_tree.h \ |
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h index 42daa7bc2..de66ac661 100644 --- a/src/fs/fs_api.h +++ b/src/fs/fs_api.h | |||
@@ -1161,6 +1161,18 @@ struct GNUNET_FS_PublishContext | |||
1161 | struct GNUNET_DATASTORE_QueueEntry *qre; | 1161 | struct GNUNET_DATASTORE_QueueEntry *qre; |
1162 | 1162 | ||
1163 | /** | 1163 | /** |
1164 | * Context for SKS publishing operation that is part of this publishing operation | ||
1165 | * (NULL if not active). | ||
1166 | */ | ||
1167 | struct GNUNET_FS_PublishSksContext *sks_pc; | ||
1168 | |||
1169 | /** | ||
1170 | * Context for KSK publishing operation that is part of this publishing operation | ||
1171 | * (NULL if not active). | ||
1172 | */ | ||
1173 | struct GNUNET_FS_PublishKskContext *ksk_pc; | ||
1174 | |||
1175 | /** | ||
1164 | * ID of the task performing the upload. NO_TASK if the upload has | 1176 | * ID of the task performing the upload. NO_TASK if the upload has |
1165 | * completed. | 1177 | * completed. |
1166 | */ | 1178 | */ |
@@ -1178,17 +1190,6 @@ struct GNUNET_FS_PublishContext | |||
1178 | uint32_t reserve_entries; | 1190 | uint32_t reserve_entries; |
1179 | 1191 | ||
1180 | /** | 1192 | /** |
1181 | * Typically GNUNET_NO. Set to GNUNET_YES if "upload_task" is | ||
1182 | * GNUNET_SCHEDULER_NO_TASK and we're waiting for a response from | ||
1183 | * the datastore service (in which case this struct must not be | ||
1184 | * freed until we have that response). If someone tries to stop the | ||
1185 | * download for good during this period, "in_network_wait" is set to | ||
1186 | * GNUNET_SYSERR which will cause the struct to be destroyed right | ||
1187 | * after we have the reply (or timeout) from the datastore service. | ||
1188 | */ | ||
1189 | int in_network_wait; | ||
1190 | |||
1191 | /** | ||
1192 | * Options for publishing. | 1193 | * Options for publishing. |
1193 | */ | 1194 | */ |
1194 | enum GNUNET_FS_PublishOptions options; | 1195 | enum GNUNET_FS_PublishOptions options; |
diff --git a/src/fs/fs_list_indexed.c b/src/fs/fs_list_indexed.c index 0896de347..784c9881a 100644 --- a/src/fs/fs_list_indexed.c +++ b/src/fs/fs_list_indexed.c | |||
@@ -34,7 +34,7 @@ | |||
34 | /** | 34 | /** |
35 | * Context for "GNUNET_FS_get_indexed_files". | 35 | * Context for "GNUNET_FS_get_indexed_files". |
36 | */ | 36 | */ |
37 | struct GetIndexedContext | 37 | struct GNUNET_FS_GetIndexedContext |
38 | { | 38 | { |
39 | /** | 39 | /** |
40 | * Handle to global FS context. | 40 | * Handle to global FS context. |
@@ -72,13 +72,13 @@ struct GetIndexedContext | |||
72 | * Function called on each response from the FS | 72 | * Function called on each response from the FS |
73 | * service with information about indexed files. | 73 | * service with information about indexed files. |
74 | * | 74 | * |
75 | * @param cls closure (of type "struct GetIndexedContext*") | 75 | * @param cls closure (of type "struct GNUNET_FS_GetIndexedContext*") |
76 | * @param msg message with indexing information | 76 | * @param msg message with indexing information |
77 | */ | 77 | */ |
78 | static void | 78 | static void |
79 | handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg) | 79 | handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg) |
80 | { | 80 | { |
81 | struct GetIndexedContext *gic = cls; | 81 | struct GNUNET_FS_GetIndexedContext *gic = cls; |
82 | const struct IndexInfoMessage *iim; | 82 | const struct IndexInfoMessage *iim; |
83 | uint16_t msize; | 83 | uint16_t msize; |
84 | const char *filename; | 84 | const char *filename; |
@@ -89,19 +89,15 @@ handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg) | |||
89 | _ | 89 | _ |
90 | ("Failed to receive response for `%s' request from `%s' service.\n"), | 90 | ("Failed to receive response for `%s' request from `%s' service.\n"), |
91 | "GET_INDEXED", "fs"); | 91 | "GET_INDEXED", "fs"); |
92 | GNUNET_SCHEDULER_add_continuation (gic->cont, gic->cont_cls, | 92 | (void) gic->iterator (gic->iterator_cls, NULL, NULL); |
93 | GNUNET_SCHEDULER_REASON_TIMEOUT); | 93 | GNUNET_FS_get_indexed_files_cancel (gic); |
94 | GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO); | ||
95 | GNUNET_free (gic); | ||
96 | return; | 94 | return; |
97 | } | 95 | } |
98 | if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END) | 96 | if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END) |
99 | { | 97 | { |
100 | /* normal end-of-list */ | 98 | /* normal end-of-list */ |
101 | GNUNET_SCHEDULER_add_continuation (gic->cont, gic->cont_cls, | 99 | (void) gic->iterator (gic->iterator_cls, NULL, NULL); |
102 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 100 | GNUNET_FS_get_indexed_files_cancel (gic); |
103 | GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO); | ||
104 | GNUNET_free (gic); | ||
105 | return; | 101 | return; |
106 | } | 102 | } |
107 | msize = ntohs (msg->size); | 103 | msize = ntohs (msg->size); |
@@ -116,18 +112,13 @@ handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg) | |||
116 | _ | 112 | _ |
117 | ("Failed to receive valid response for `%s' request from `%s' service.\n"), | 113 | ("Failed to receive valid response for `%s' request from `%s' service.\n"), |
118 | "GET_INDEXED", "fs"); | 114 | "GET_INDEXED", "fs"); |
119 | GNUNET_SCHEDULER_add_continuation (gic->cont, gic->cont_cls, | 115 | (void) gic->iterator (gic->iterator_cls, NULL, NULL); |
120 | GNUNET_SCHEDULER_REASON_TIMEOUT); | 116 | GNUNET_FS_get_indexed_files_cancel (gic); |
121 | GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO); | ||
122 | GNUNET_free (gic); | ||
123 | return; | 117 | return; |
124 | } | 118 | } |
125 | if (GNUNET_OK != gic->iterator (gic->iterator_cls, filename, &iim->file_id)) | 119 | if (GNUNET_OK != gic->iterator (gic->iterator_cls, filename, &iim->file_id)) |
126 | { | 120 | { |
127 | GNUNET_SCHEDULER_add_continuation (gic->cont, gic->cont_cls, | 121 | GNUNET_FS_get_indexed_files_cancel (gic); |
128 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
129 | GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO); | ||
130 | GNUNET_free (gic); | ||
131 | return; | 122 | return; |
132 | } | 123 | } |
133 | /* get more */ | 124 | /* get more */ |
@@ -142,19 +133,15 @@ handle_index_info (void *cls, const struct GNUNET_MessageHeader *msg) | |||
142 | * @param h handle to the file sharing subsystem | 133 | * @param h handle to the file sharing subsystem |
143 | * @param iterator function to call on each indexed file | 134 | * @param iterator function to call on each indexed file |
144 | * @param iterator_cls closure for iterator | 135 | * @param iterator_cls closure for iterator |
145 | * @param cont continuation to call when done; | 136 | * @return NULL on error ('iter' is not called) |
146 | * reason should be "TIMEOUT" (on | ||
147 | * error) or "PREREQ_DONE" (on success) | ||
148 | * @param cont_cls closure for cont | ||
149 | */ | 137 | */ |
150 | void | 138 | struct GNUNET_FS_GetIndexedContext * |
151 | GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | 139 | GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, |
152 | GNUNET_FS_IndexedFileProcessor iterator, | 140 | GNUNET_FS_IndexedFileProcessor iterator, |
153 | void *iterator_cls, GNUNET_SCHEDULER_Task cont, | 141 | void *iterator_cls) |
154 | void *cont_cls) | ||
155 | { | 142 | { |
156 | struct GNUNET_CLIENT_Connection *client; | 143 | struct GNUNET_CLIENT_Connection *client; |
157 | struct GetIndexedContext *gic; | 144 | struct GNUNET_FS_GetIndexedContext *gic; |
158 | struct GNUNET_MessageHeader msg; | 145 | struct GNUNET_MessageHeader msg; |
159 | 146 | ||
160 | client = GNUNET_CLIENT_connect ("fs", h->cfg); | 147 | client = GNUNET_CLIENT_connect ("fs", h->cfg); |
@@ -162,18 +149,13 @@ GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | |||
162 | { | 149 | { |
163 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 150 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
164 | _("Failed to not connect to `%s' service.\n"), "fs"); | 151 | _("Failed to not connect to `%s' service.\n"), "fs"); |
165 | GNUNET_SCHEDULER_add_continuation (cont, cont_cls, | 152 | return NULL; |
166 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
167 | return; | ||
168 | } | 153 | } |
169 | 154 | gic = GNUNET_malloc (sizeof (struct GNUNET_FS_GetIndexedContext)); | |
170 | gic = GNUNET_malloc (sizeof (struct GetIndexedContext)); | ||
171 | gic->h = h; | 155 | gic->h = h; |
172 | gic->client = client; | 156 | gic->client = client; |
173 | gic->iterator = iterator; | 157 | gic->iterator = iterator; |
174 | gic->iterator_cls = iterator_cls; | 158 | gic->iterator_cls = iterator_cls; |
175 | gic->cont = cont; | ||
176 | gic->cont_cls = cont_cls; | ||
177 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | 159 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); |
178 | msg.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); | 160 | msg.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); |
179 | GNUNET_assert (GNUNET_OK == | 161 | GNUNET_assert (GNUNET_OK == |
@@ -182,6 +164,21 @@ GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | |||
182 | GNUNET_YES, | 164 | GNUNET_YES, |
183 | &handle_index_info, | 165 | &handle_index_info, |
184 | gic)); | 166 | gic)); |
167 | return gic; | ||
168 | } | ||
169 | |||
170 | |||
171 | /** | ||
172 | * Cancel iteration over all indexed files. | ||
173 | * | ||
174 | * @param gic operation to cancel | ||
175 | */ | ||
176 | void | ||
177 | GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic) | ||
178 | { | ||
179 | GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO); | ||
180 | GNUNET_free (gic); | ||
185 | } | 181 | } |
186 | 182 | ||
183 | |||
187 | /* end of fs_list_indexed.c */ | 184 | /* end of fs_list_indexed.c */ |
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index 9cb8cd5a4..e7cf38800 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c | |||
@@ -30,19 +30,12 @@ | |||
30 | #include "gnunet_fs_service.h" | 30 | #include "gnunet_fs_service.h" |
31 | #include "fs_api.h" | 31 | #include "fs_api.h" |
32 | 32 | ||
33 | #define DEBUG_NAMESPACE GNUNET_EXTRA_LOGGING | ||
34 | |||
35 | 33 | ||
36 | /** | 34 | /** |
37 | * Maximum legal size for an sblock. | 35 | * Maximum legal size for an sblock. |
38 | */ | 36 | */ |
39 | #define MAX_SBLOCK_SIZE (60 * 1024) | 37 | #define MAX_SBLOCK_SIZE (60 * 1024) |
40 | 38 | ||
41 | /** | ||
42 | * Maximum legal size for an nblock. | ||
43 | */ | ||
44 | #define MAX_NBLOCK_SIZE (60 * 1024) | ||
45 | |||
46 | 39 | ||
47 | /** | 40 | /** |
48 | * Return the name of the directory in which we store | 41 | * Return the name of the directory in which we store |
@@ -233,253 +226,6 @@ END: | |||
233 | } | 226 | } |
234 | 227 | ||
235 | 228 | ||
236 | /** | ||
237 | * Context for advertising a namespace. | ||
238 | */ | ||
239 | struct AdvertisementContext | ||
240 | { | ||
241 | /** | ||
242 | * Function to call with the result. | ||
243 | */ | ||
244 | GNUNET_FS_PublishContinuation cont; | ||
245 | |||
246 | /** | ||
247 | * Closure for cont. | ||
248 | */ | ||
249 | void *cont_cls; | ||
250 | |||
251 | /** | ||
252 | * Datastore handle. | ||
253 | */ | ||
254 | struct GNUNET_DATASTORE_Handle *dsh; | ||
255 | |||
256 | /** | ||
257 | * Our KSK URI. | ||
258 | */ | ||
259 | struct GNUNET_FS_Uri *ksk_uri; | ||
260 | |||
261 | /** | ||
262 | * Plaintext. | ||
263 | */ | ||
264 | char *pt; | ||
265 | |||
266 | /** | ||
267 | * NBlock to sign and store. | ||
268 | */ | ||
269 | struct NBlock *nb; | ||
270 | |||
271 | /** | ||
272 | * The namespace. | ||
273 | */ | ||
274 | struct GNUNET_FS_Namespace *ns; | ||
275 | |||
276 | /** | ||
277 | * Block options. | ||
278 | */ | ||
279 | struct GNUNET_FS_BlockOptions bo; | ||
280 | |||
281 | /** | ||
282 | * Number of bytes of plaintext. | ||
283 | */ | ||
284 | size_t pt_size; | ||
285 | |||
286 | /** | ||
287 | * Current keyword offset. | ||
288 | */ | ||
289 | unsigned int pos; | ||
290 | }; | ||
291 | |||
292 | |||
293 | /** | ||
294 | * Disconnect from the datastore. | ||
295 | * | ||
296 | * @param cls datastore handle | ||
297 | * @param tc scheduler context | ||
298 | */ | ||
299 | static void | ||
300 | do_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
301 | { | ||
302 | struct GNUNET_DATASTORE_Handle *dsh = cls; | ||
303 | |||
304 | GNUNET_DATASTORE_disconnect (dsh, GNUNET_NO); | ||
305 | } | ||
306 | |||
307 | |||
308 | /** | ||
309 | * Continuation called to notify client about result of the | ||
310 | * operation. | ||
311 | * | ||
312 | * @param cls closure (our struct AdvertismentContext) | ||
313 | * @param success GNUNET_SYSERR on failure | ||
314 | * @param min_expiration minimum expiration time required for content to be stored | ||
315 | * @param msg NULL on success, otherwise an error message | ||
316 | */ | ||
317 | static void | ||
318 | advertisement_cont (void *cls, int success, | ||
319 | struct GNUNET_TIME_Absolute min_expiration, | ||
320 | const char *msg) | ||
321 | { | ||
322 | struct AdvertisementContext *ac = cls; | ||
323 | const char *keyword; | ||
324 | GNUNET_HashCode key; | ||
325 | GNUNET_HashCode query; | ||
326 | struct GNUNET_CRYPTO_AesSessionKey skey; | ||
327 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
328 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; | ||
329 | |||
330 | if (GNUNET_OK != success) | ||
331 | { | ||
332 | /* error! */ | ||
333 | GNUNET_SCHEDULER_add_continuation (&do_disconnect, ac->dsh, | ||
334 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
335 | if (msg == NULL) | ||
336 | { | ||
337 | GNUNET_break (0); | ||
338 | msg = _("Unknown error"); | ||
339 | } | ||
340 | if (ac->cont != NULL) | ||
341 | ac->cont (ac->cont_cls, NULL, msg); | ||
342 | GNUNET_FS_uri_destroy (ac->ksk_uri); | ||
343 | GNUNET_free (ac->pt); | ||
344 | GNUNET_free (ac->nb); | ||
345 | GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO); | ||
346 | GNUNET_free (ac); | ||
347 | return; | ||
348 | } | ||
349 | if (ac->pos == ac->ksk_uri->data.ksk.keywordCount) | ||
350 | { | ||
351 | /* done! */ | ||
352 | GNUNET_SCHEDULER_add_continuation (&do_disconnect, ac->dsh, | ||
353 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
354 | if (ac->cont != NULL) | ||
355 | ac->cont (ac->cont_cls, ac->ksk_uri, NULL); | ||
356 | GNUNET_FS_uri_destroy (ac->ksk_uri); | ||
357 | GNUNET_free (ac->pt); | ||
358 | GNUNET_free (ac->nb); | ||
359 | GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO); | ||
360 | GNUNET_free (ac); | ||
361 | return; | ||
362 | } | ||
363 | keyword = ac->ksk_uri->data.ksk.keywords[ac->pos++]; | ||
364 | /* first character of keyword indicates if it is | ||
365 | * mandatory or not -- ignore for hashing */ | ||
366 | GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); | ||
367 | GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); | ||
368 | GNUNET_CRYPTO_aes_encrypt (ac->pt, ac->pt_size, &skey, &iv, &ac->nb[1]); | ||
369 | GNUNET_break (GNUNET_OK == | ||
370 | GNUNET_CRYPTO_rsa_sign (ac->ns->key, &ac->nb->ns_purpose, | ||
371 | &ac->nb->ns_signature)); | ||
372 | pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); | ||
373 | GNUNET_assert (pk != NULL); | ||
374 | GNUNET_CRYPTO_rsa_key_get_public (pk, &ac->nb->keyspace); | ||
375 | GNUNET_CRYPTO_hash (&ac->nb->keyspace, | ||
376 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
377 | &query); | ||
378 | GNUNET_break (GNUNET_OK == | ||
379 | GNUNET_CRYPTO_rsa_sign (pk, &ac->nb->ksk_purpose, | ||
380 | &ac->nb->ksk_signature)); | ||
381 | GNUNET_CRYPTO_rsa_key_free (pk); | ||
382 | GNUNET_DATASTORE_put (ac->dsh, 0 /* no reservation */ , | ||
383 | &query, ac->pt_size + sizeof (struct NBlock), ac->nb, | ||
384 | GNUNET_BLOCK_TYPE_FS_NBLOCK, ac->bo.content_priority, | ||
385 | ac->bo.anonymity_level, ac->bo.replication_level, | ||
386 | ac->bo.expiration_time, -2, 1, | ||
387 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &advertisement_cont, | ||
388 | ac); | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Publish an advertismement for a namespace. | ||
394 | * | ||
395 | * @param h handle to the file sharing subsystem | ||
396 | * @param ksk_uri keywords to use for advertisment | ||
397 | * @param namespace handle for the namespace that should be advertised | ||
398 | * @param meta meta-data for the namespace advertisement | ||
399 | * @param bo block options | ||
400 | * @param rootEntry name of the root of the namespace | ||
401 | * @param cont continuation | ||
402 | * @param cont_cls closure for cont | ||
403 | */ | ||
404 | void | ||
405 | GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, | ||
406 | struct GNUNET_FS_Uri *ksk_uri, | ||
407 | struct GNUNET_FS_Namespace *namespace, | ||
408 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
409 | const struct GNUNET_FS_BlockOptions *bo, | ||
410 | const char *rootEntry, | ||
411 | GNUNET_FS_PublishContinuation cont, | ||
412 | void *cont_cls) | ||
413 | { | ||
414 | size_t reslen; | ||
415 | size_t size; | ||
416 | ssize_t mdsize; | ||
417 | struct NBlock *nb; | ||
418 | char *mdst; | ||
419 | struct GNUNET_DATASTORE_Handle *dsh; | ||
420 | struct AdvertisementContext *ctx; | ||
421 | char *pt; | ||
422 | |||
423 | /* create advertisements */ | ||
424 | mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
425 | if (-1 == mdsize) | ||
426 | { | ||
427 | cont (cont_cls, NULL, _("Failed to serialize meta data")); | ||
428 | return; | ||
429 | } | ||
430 | reslen = strlen (rootEntry) + 1; | ||
431 | size = mdsize + sizeof (struct NBlock) + reslen; | ||
432 | if (size > MAX_NBLOCK_SIZE) | ||
433 | { | ||
434 | size = MAX_NBLOCK_SIZE; | ||
435 | mdsize = size - sizeof (struct NBlock) - reslen; | ||
436 | } | ||
437 | |||
438 | pt = GNUNET_malloc (mdsize + reslen); | ||
439 | memcpy (pt, rootEntry, reslen); | ||
440 | mdst = &pt[reslen]; | ||
441 | mdsize = | ||
442 | GNUNET_CONTAINER_meta_data_serialize (meta, &mdst, mdsize, | ||
443 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
444 | if (mdsize == -1) | ||
445 | { | ||
446 | GNUNET_break (0); | ||
447 | GNUNET_free (pt); | ||
448 | cont (cont_cls, NULL, _("Failed to serialize meta data")); | ||
449 | return; | ||
450 | } | ||
451 | size = mdsize + sizeof (struct NBlock) + reslen; | ||
452 | nb = GNUNET_malloc (size); | ||
453 | GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &nb->subspace); | ||
454 | nb->ns_purpose.size = | ||
455 | htonl (mdsize + reslen + | ||
456 | sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
457 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
458 | nb->ns_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK); | ||
459 | nb->ksk_purpose.size = | ||
460 | htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature)); | ||
461 | nb->ksk_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG); | ||
462 | dsh = GNUNET_DATASTORE_connect (h->cfg); | ||
463 | if (NULL == dsh) | ||
464 | { | ||
465 | GNUNET_free (nb); | ||
466 | GNUNET_free (pt); | ||
467 | cont (cont_cls, NULL, _("Failed to connect to datastore service")); | ||
468 | return; | ||
469 | } | ||
470 | ctx = GNUNET_malloc (sizeof (struct AdvertisementContext)); | ||
471 | ctx->cont = cont; | ||
472 | ctx->cont_cls = cont_cls; | ||
473 | ctx->dsh = dsh; | ||
474 | ctx->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); | ||
475 | ctx->nb = nb; | ||
476 | ctx->pt = pt; | ||
477 | ctx->pt_size = mdsize + reslen; | ||
478 | ctx->ns = namespace; | ||
479 | ctx->ns->rc++; | ||
480 | ctx->bo = *bo; | ||
481 | advertisement_cont (ctx, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); | ||
482 | } | ||
483 | 229 | ||
484 | 230 | ||
485 | /** | 231 | /** |
@@ -557,26 +303,25 @@ GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, int freeze) | |||
557 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", | 303 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", |
558 | namespace->filename); | 304 | namespace->filename); |
559 | } | 305 | } |
560 | if (0 == namespace->rc) | 306 | if (0 != namespace->rc) |
307 | return GNUNET_OK; | ||
308 | GNUNET_CRYPTO_rsa_key_free (namespace->key); | ||
309 | GNUNET_free (namespace->filename); | ||
310 | GNUNET_free (namespace->name); | ||
311 | for (i = 0; i < namespace->update_node_count; i++) | ||
561 | { | 312 | { |
562 | GNUNET_CRYPTO_rsa_key_free (namespace->key); | 313 | nsn = namespace->update_nodes[i]; |
563 | GNUNET_free (namespace->filename); | 314 | GNUNET_CONTAINER_meta_data_destroy (nsn->md); |
564 | GNUNET_free (namespace->name); | 315 | GNUNET_FS_uri_destroy (nsn->uri); |
565 | for (i = 0; i < namespace->update_node_count; i++) | 316 | GNUNET_free (nsn->id); |
566 | { | 317 | GNUNET_free (nsn->update); |
567 | nsn = namespace->update_nodes[i]; | 318 | GNUNET_free (nsn); |
568 | GNUNET_CONTAINER_meta_data_destroy (nsn->md); | 319 | } |
569 | GNUNET_FS_uri_destroy (nsn->uri); | 320 | GNUNET_array_grow (namespace->update_nodes, namespace->update_node_count, |
570 | GNUNET_free (nsn->id); | 321 | 0); |
571 | GNUNET_free (nsn->update); | 322 | if (namespace->update_map != NULL) |
572 | GNUNET_free (nsn); | 323 | GNUNET_CONTAINER_multihashmap_destroy (namespace->update_map); |
573 | } | 324 | GNUNET_free (namespace); |
574 | GNUNET_array_grow (namespace->update_nodes, namespace->update_node_count, | ||
575 | 0); | ||
576 | if (namespace->update_map != NULL) | ||
577 | GNUNET_CONTAINER_multihashmap_destroy (namespace->update_map); | ||
578 | GNUNET_free (namespace); | ||
579 | } | ||
580 | return GNUNET_OK; | 325 | return GNUNET_OK; |
581 | } | 326 | } |
582 | 327 | ||
@@ -666,12 +411,10 @@ GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h, | |||
666 | } | 411 | } |
667 | 412 | ||
668 | 413 | ||
669 | |||
670 | |||
671 | /** | 414 | /** |
672 | * Context for the SKS publication. | 415 | * Context for the SKS publication. |
673 | */ | 416 | */ |
674 | struct PublishSksContext | 417 | struct GNUNET_FS_PublishSksContext |
675 | { | 418 | { |
676 | 419 | ||
677 | /** | 420 | /** |
@@ -705,6 +448,10 @@ struct PublishSksContext | |||
705 | */ | 448 | */ |
706 | void *cont_cls; | 449 | void *cont_cls; |
707 | 450 | ||
451 | /** | ||
452 | * Handle for our datastore request. | ||
453 | */ | ||
454 | struct GNUNET_DATASTORE_QueueEntry *dqe; | ||
708 | }; | 455 | }; |
709 | 456 | ||
710 | 457 | ||
@@ -712,7 +459,7 @@ struct PublishSksContext | |||
712 | * Function called by the datastore API with | 459 | * Function called by the datastore API with |
713 | * the result from the PUT (SBlock) request. | 460 | * the result from the PUT (SBlock) request. |
714 | * | 461 | * |
715 | * @param cls closure of type "struct PublishSksContext*" | 462 | * @param cls closure of type "struct GNUNET_FS_PublishSksContext*" |
716 | * @param success GNUNET_OK on success | 463 | * @param success GNUNET_OK on success |
717 | * @param min_expiration minimum expiration time required for content to be stored | 464 | * @param min_expiration minimum expiration time required for content to be stored |
718 | * @param msg error message (or NULL) | 465 | * @param msg error message (or NULL) |
@@ -722,54 +469,39 @@ sb_put_cont (void *cls, int success, | |||
722 | struct GNUNET_TIME_Absolute min_expiration, | 469 | struct GNUNET_TIME_Absolute min_expiration, |
723 | const char *msg) | 470 | const char *msg) |
724 | { | 471 | { |
725 | struct PublishSksContext *psc = cls; | 472 | struct GNUNET_FS_PublishSksContext *psc = cls; |
726 | GNUNET_HashCode hc; | 473 | GNUNET_HashCode hc; |
727 | 474 | ||
728 | if (NULL != psc->dsh) | 475 | psc->dqe = NULL; |
729 | { | ||
730 | GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); | ||
731 | psc->dsh = NULL; | ||
732 | } | ||
733 | if (GNUNET_OK != success) | 476 | if (GNUNET_OK != success) |
734 | { | 477 | { |
735 | if (psc->cont != NULL) | 478 | if (NULL != psc->cont) |
736 | psc->cont (psc->cont_cls, NULL, msg); | 479 | psc->cont (psc->cont_cls, NULL, msg); |
480 | GNUNET_FS_publish_sks_cancel (psc); | ||
481 | return; | ||
737 | } | 482 | } |
738 | else | 483 | if (NULL != psc->nsn) |
739 | { | 484 | { |
740 | if (psc->nsn != NULL) | 485 | /* FIXME: this can be done much more |
486 | * efficiently by simply appending to the | ||
487 | * file and overwriting the 4-byte header */ | ||
488 | if (psc->namespace->update_nodes == NULL) | ||
489 | read_update_information_graph (psc->namespace); | ||
490 | GNUNET_array_append (psc->namespace->update_nodes, | ||
491 | psc->namespace->update_node_count, psc->nsn); | ||
492 | if (psc->namespace->update_map != NULL) | ||
741 | { | 493 | { |
742 | /* FIXME: this can be done much more | 494 | GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc); |
743 | * efficiently by simply appending to the | 495 | GNUNET_CONTAINER_multihashmap_put (psc->namespace->update_map, &hc, |
744 | * file and overwriting the 4-byte header */ | 496 | psc->nsn, |
745 | if (psc->namespace->update_nodes == NULL) | 497 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
746 | read_update_information_graph (psc->namespace); | ||
747 | GNUNET_array_append (psc->namespace->update_nodes, | ||
748 | psc->namespace->update_node_count, psc->nsn); | ||
749 | if (psc->namespace->update_map != NULL) | ||
750 | { | ||
751 | GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc); | ||
752 | GNUNET_CONTAINER_multihashmap_put (psc->namespace->update_map, &hc, | ||
753 | psc->nsn, | ||
754 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
755 | } | ||
756 | psc->nsn = NULL; | ||
757 | write_update_information_graph (psc->namespace); | ||
758 | } | 498 | } |
759 | if (psc->cont != NULL) | 499 | psc->nsn = NULL; |
760 | psc->cont (psc->cont_cls, psc->uri, NULL); | 500 | write_update_information_graph (psc->namespace); |
761 | } | ||
762 | GNUNET_FS_namespace_delete (psc->namespace, GNUNET_NO); | ||
763 | GNUNET_FS_uri_destroy (psc->uri); | ||
764 | if (psc->nsn != NULL) | ||
765 | { | ||
766 | GNUNET_CONTAINER_meta_data_destroy (psc->nsn->md); | ||
767 | GNUNET_FS_uri_destroy (psc->nsn->uri); | ||
768 | GNUNET_free (psc->nsn->id); | ||
769 | GNUNET_free (psc->nsn->update); | ||
770 | GNUNET_free (psc->nsn); | ||
771 | } | 501 | } |
772 | GNUNET_free (psc); | 502 | if (NULL != psc->cont) |
503 | psc->cont (psc->cont_cls, psc->uri, NULL); | ||
504 | GNUNET_FS_publish_sks_cancel (psc); | ||
773 | } | 505 | } |
774 | 506 | ||
775 | 507 | ||
@@ -786,8 +518,9 @@ sb_put_cont (void *cls, int success, | |||
786 | * @param options publication options | 518 | * @param options publication options |
787 | * @param cont continuation | 519 | * @param cont continuation |
788 | * @param cont_cls closure for cont | 520 | * @param cont_cls closure for cont |
521 | * @return NULL on error ('cont' will still be called) | ||
789 | */ | 522 | */ |
790 | void | 523 | struct GNUNET_FS_PublishSksContext * |
791 | GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | 524 | GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, |
792 | struct GNUNET_FS_Namespace *namespace, | 525 | struct GNUNET_FS_Namespace *namespace, |
793 | const char *identifier, const char *update, | 526 | const char *identifier, const char *update, |
@@ -797,7 +530,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
797 | enum GNUNET_FS_PublishOptions options, | 530 | enum GNUNET_FS_PublishOptions options, |
798 | GNUNET_FS_PublishContinuation cont, void *cont_cls) | 531 | GNUNET_FS_PublishContinuation cont, void *cont_cls) |
799 | { | 532 | { |
800 | struct PublishSksContext *psc; | 533 | struct GNUNET_FS_PublishSksContext *psc; |
801 | struct GNUNET_CRYPTO_AesSessionKey sk; | 534 | struct GNUNET_CRYPTO_AesSessionKey sk; |
802 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 535 | struct GNUNET_CRYPTO_AesInitializationVector iv; |
803 | struct GNUNET_FS_Uri *sks_uri; | 536 | struct GNUNET_FS_Uri *sks_uri; |
@@ -851,8 +584,9 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
851 | { | 584 | { |
852 | GNUNET_break (0); | 585 | GNUNET_break (0); |
853 | GNUNET_free (sb); | 586 | GNUNET_free (sb); |
854 | cont (cont_cls, NULL, _("Internal error.")); | 587 | if (NULL != cont) |
855 | return; | 588 | cont (cont_cls, NULL, _("Internal error.")); |
589 | return NULL; | ||
856 | } | 590 | } |
857 | size = sizeof (struct SBlock) + mdsize + slen + nidlen; | 591 | size = sizeof (struct SBlock) + mdsize + slen + nidlen; |
858 | sb_enc = GNUNET_malloc (size); | 592 | sb_enc = GNUNET_malloc (size); |
@@ -877,18 +611,17 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
877 | GNUNET_assert (GNUNET_OK == | 611 | GNUNET_assert (GNUNET_OK == |
878 | GNUNET_CRYPTO_rsa_sign (namespace->key, &sb_enc->purpose, | 612 | GNUNET_CRYPTO_rsa_sign (namespace->key, &sb_enc->purpose, |
879 | &sb_enc->signature)); | 613 | &sb_enc->signature)); |
880 | psc = GNUNET_malloc (sizeof (struct PublishSksContext)); | 614 | psc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishSksContext)); |
881 | psc->uri = sks_uri; | 615 | psc->uri = sks_uri; |
882 | psc->cont = cont; | 616 | psc->cont = cont; |
883 | psc->namespace = namespace; | 617 | psc->namespace = GNUNET_FS_namespace_dup (namespace); |
884 | namespace->rc++; | ||
885 | psc->cont_cls = cont_cls; | 618 | psc->cont_cls = cont_cls; |
886 | if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | 619 | if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) |
887 | { | 620 | { |
888 | GNUNET_free (sb_enc); | 621 | GNUNET_free (sb_enc); |
889 | GNUNET_free (sb); | 622 | GNUNET_free (sb); |
890 | sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); | 623 | sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); |
891 | return; | 624 | return NULL; |
892 | } | 625 | } |
893 | psc->dsh = GNUNET_DATASTORE_connect (h->cfg); | 626 | psc->dsh = GNUNET_DATASTORE_connect (h->cfg); |
894 | if (NULL == psc->dsh) | 627 | if (NULL == psc->dsh) |
@@ -896,7 +629,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
896 | GNUNET_free (sb_enc); | 629 | GNUNET_free (sb_enc); |
897 | GNUNET_free (sb); | 630 | GNUNET_free (sb); |
898 | sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); | 631 | sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); |
899 | return; | 632 | return NULL; |
900 | } | 633 | } |
901 | GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, &id, &query); | 634 | GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, &id, &query); |
902 | if (NULL != update) | 635 | if (NULL != update) |
@@ -907,13 +640,46 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
907 | psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); | 640 | psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); |
908 | psc->nsn->uri = GNUNET_FS_uri_dup (uri); | 641 | psc->nsn->uri = GNUNET_FS_uri_dup (uri); |
909 | } | 642 | } |
910 | GNUNET_DATASTORE_put (psc->dsh, 0, &sb_enc->identifier, size, sb_enc, | 643 | psc->dqe = GNUNET_DATASTORE_put (psc->dsh, 0, &sb_enc->identifier, size, sb_enc, |
911 | GNUNET_BLOCK_TYPE_FS_SBLOCK, bo->content_priority, | 644 | GNUNET_BLOCK_TYPE_FS_SBLOCK, bo->content_priority, |
912 | bo->anonymity_level, bo->replication_level, | 645 | bo->anonymity_level, bo->replication_level, |
913 | bo->expiration_time, -2, 1, | 646 | bo->expiration_time, -2, 1, |
914 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); | 647 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); |
915 | GNUNET_free (sb); | 648 | GNUNET_free (sb); |
916 | GNUNET_free (sb_enc); | 649 | GNUNET_free (sb_enc); |
650 | return psc; | ||
651 | } | ||
652 | |||
653 | |||
654 | /** | ||
655 | * Abort the SKS publishing operation. | ||
656 | * | ||
657 | * @param sc context of the operation to abort. | ||
658 | */ | ||
659 | void | ||
660 | GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc) | ||
661 | { | ||
662 | if (NULL != psc->dqe) | ||
663 | { | ||
664 | GNUNET_DATASTORE_cancel (psc->dqe); | ||
665 | psc->dqe = NULL; | ||
666 | } | ||
667 | if (NULL != psc->dsh) | ||
668 | { | ||
669 | GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); | ||
670 | psc->dsh = NULL; | ||
671 | } | ||
672 | GNUNET_FS_namespace_delete (psc->namespace, GNUNET_NO); | ||
673 | GNUNET_FS_uri_destroy (psc->uri); | ||
674 | if (NULL != psc->nsn) | ||
675 | { | ||
676 | GNUNET_CONTAINER_meta_data_destroy (psc->nsn->md); | ||
677 | GNUNET_FS_uri_destroy (psc->nsn->uri); | ||
678 | GNUNET_free (psc->nsn->id); | ||
679 | GNUNET_free (psc->nsn->update); | ||
680 | GNUNET_free (psc->nsn); | ||
681 | } | ||
682 | GNUNET_free (psc); | ||
917 | } | 683 | } |
918 | 684 | ||
919 | 685 | ||
@@ -1081,10 +847,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1081 | read_update_information_graph (namespace); | 847 | read_update_information_graph (namespace); |
1082 | if (namespace->update_nodes == NULL) | 848 | if (namespace->update_nodes == NULL) |
1083 | { | 849 | { |
1084 | #if DEBUG_NAMESPACE | ||
1085 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 850 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1086 | "No updateable nodes found for ID `%s'\n", next_id); | 851 | "No updateable nodes found for ID `%s'\n", next_id); |
1087 | #endif | ||
1088 | return; /* no nodes */ | 852 | return; /* no nodes */ |
1089 | } | 853 | } |
1090 | if (namespace->update_map == NULL) | 854 | if (namespace->update_map == NULL) |
@@ -1111,10 +875,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1111 | &process_update_node, &pc); | 875 | &process_update_node, &pc); |
1112 | return; | 876 | return; |
1113 | } | 877 | } |
1114 | #if DEBUG_NAMESPACE | ||
1115 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 878 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1116 | "Calculating TREEs to find roots of update trees\n"); | 879 | "Calculating TREEs to find roots of update trees\n"); |
1117 | #endif | ||
1118 | /* Find heads of TREEs in update graph */ | 880 | /* Find heads of TREEs in update graph */ |
1119 | nug = ++namespace->nug_gen; | 881 | nug = ++namespace->nug_gen; |
1120 | fc.tree_array = NULL; | 882 | fc.tree_array = NULL; |
@@ -1125,10 +887,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1125 | nsn = namespace->update_nodes[i]; | 887 | nsn = namespace->update_nodes[i]; |
1126 | if (nsn->nug == nug) | 888 | if (nsn->nug == nug) |
1127 | { | 889 | { |
1128 | #if DEBUG_NAMESPACE | ||
1129 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, | 890 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, |
1130 | nsn->nug); | 891 | nsn->nug); |
1131 | #endif | ||
1132 | continue; /* already placed in TREE */ | 892 | continue; /* already placed in TREE */ |
1133 | } | 893 | } |
1134 | GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); | 894 | GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); |
@@ -1156,11 +916,9 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1156 | GNUNET_array_append (fc.tree_array, fc.tree_array_size, nsn); | 916 | GNUNET_array_append (fc.tree_array, fc.tree_array_size, nsn); |
1157 | nsn->tree_id = fc.id; | 917 | nsn->tree_id = fc.id; |
1158 | } | 918 | } |
1159 | #if DEBUG_NAMESPACE | ||
1160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1161 | "Starting new TREE %u with node `%s'\n", nsn->tree_id, | 920 | "Starting new TREE %u with node `%s'\n", nsn->tree_id, |
1162 | nsn->id); | 921 | nsn->id); |
1163 | #endif | ||
1164 | /* put all nodes with same identifier into this TREE */ | 922 | /* put all nodes with same identifier into this TREE */ |
1165 | GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); | 923 | GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); |
1166 | fc.id = nsn->tree_id; | 924 | fc.id = nsn->tree_id; |
@@ -1175,28 +933,21 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1175 | fc.tree_array[fc.id] = nsn; | 933 | fc.tree_array[fc.id] = nsn; |
1176 | nsn->tree_id = fc.id; | 934 | nsn->tree_id = fc.id; |
1177 | } | 935 | } |
1178 | #if DEBUG_NAMESPACE | ||
1179 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, | 936 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, |
1180 | fc.id); | 937 | fc.id); |
1181 | #endif | ||
1182 | } | 938 | } |
1183 | for (i = 0; i < fc.tree_array_size; i++) | 939 | for (i = 0; i < fc.tree_array_size; i++) |
1184 | { | 940 | { |
1185 | nsn = fc.tree_array[i]; | 941 | nsn = fc.tree_array[i]; |
1186 | if (NULL != nsn) | 942 | if (NULL != nsn) |
1187 | { | 943 | { |
1188 | #if DEBUG_NAMESPACE | ||
1189 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Root of TREE %u is node `%s'\n", i, | 944 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Root of TREE %u is node `%s'\n", i, |
1190 | nsn->id); | 945 | nsn->id); |
1191 | #endif | ||
1192 | |||
1193 | ip (ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); | 946 | ip (ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); |
1194 | } | 947 | } |
1195 | } | 948 | } |
1196 | GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); | 949 | GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); |
1197 | #if DEBUG_NAMESPACE | ||
1198 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); | 950 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); |
1199 | #endif | ||
1200 | } | 951 | } |
1201 | 952 | ||
1202 | 953 | ||
diff --git a/src/fs/fs_namespace_advertise.c b/src/fs/fs_namespace_advertise.c new file mode 100644 index 000000000..60b4de095 --- /dev/null +++ b/src/fs/fs_namespace_advertise.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 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 3, 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_namespace_advertise.c | ||
23 | * @brief advertise namespaces (creating NBlocks) | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_constants.h" | ||
28 | #include "gnunet_signatures.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_fs_service.h" | ||
31 | #include "fs_api.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Maximum legal size for an nblock. | ||
36 | */ | ||
37 | #define MAX_NBLOCK_SIZE (60 * 1024) | ||
38 | |||
39 | |||
40 | /** | ||
41 | * Context for advertising a namespace. | ||
42 | */ | ||
43 | struct GNUNET_FS_AdvertisementContext | ||
44 | { | ||
45 | /** | ||
46 | * Function to call with the result. | ||
47 | */ | ||
48 | GNUNET_FS_PublishContinuation cont; | ||
49 | |||
50 | /** | ||
51 | * Closure for cont. | ||
52 | */ | ||
53 | void *cont_cls; | ||
54 | |||
55 | /** | ||
56 | * Datastore handle. | ||
57 | */ | ||
58 | struct GNUNET_DATASTORE_Handle *dsh; | ||
59 | |||
60 | /** | ||
61 | * Our KSK URI. | ||
62 | */ | ||
63 | struct GNUNET_FS_Uri *ksk_uri; | ||
64 | |||
65 | /** | ||
66 | * Plaintext. | ||
67 | */ | ||
68 | char *pt; | ||
69 | |||
70 | /** | ||
71 | * NBlock to sign and store. | ||
72 | */ | ||
73 | struct NBlock *nb; | ||
74 | |||
75 | /** | ||
76 | * The namespace. | ||
77 | */ | ||
78 | struct GNUNET_FS_Namespace *ns; | ||
79 | |||
80 | /** | ||
81 | * Current datastore queue entry for advertising. | ||
82 | */ | ||
83 | struct GNUNET_DATASTORE_QueueEntry *dqe; | ||
84 | |||
85 | /** | ||
86 | * Block options. | ||
87 | */ | ||
88 | struct GNUNET_FS_BlockOptions bo; | ||
89 | |||
90 | /** | ||
91 | * Number of bytes of plaintext. | ||
92 | */ | ||
93 | size_t pt_size; | ||
94 | |||
95 | /** | ||
96 | * Current keyword offset. | ||
97 | */ | ||
98 | unsigned int pos; | ||
99 | }; | ||
100 | |||
101 | |||
102 | // FIXME: I see no good reason why this should need to be done | ||
103 | // in a new task (anymore). Integrate with 'cancel' function below? | ||
104 | /** | ||
105 | * Disconnect from the datastore. | ||
106 | * | ||
107 | * @param cls datastore handle | ||
108 | * @param tc scheduler context | ||
109 | */ | ||
110 | static void | ||
111 | do_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
112 | { | ||
113 | struct GNUNET_DATASTORE_Handle *dsh = cls; | ||
114 | |||
115 | GNUNET_DATASTORE_disconnect (dsh, GNUNET_NO); | ||
116 | } | ||
117 | |||
118 | |||
119 | /** | ||
120 | * Continuation called to notify client about result of the | ||
121 | * operation. | ||
122 | * | ||
123 | * @param cls closure (our struct GNUNET_FS_AdvertismentContext) | ||
124 | * @param success GNUNET_SYSERR on failure | ||
125 | * @param min_expiration minimum expiration time required for content to be stored | ||
126 | * @param msg NULL on success, otherwise an error message | ||
127 | */ | ||
128 | static void | ||
129 | advertisement_cont (void *cls, int success, | ||
130 | struct GNUNET_TIME_Absolute min_expiration, | ||
131 | const char *msg) | ||
132 | { | ||
133 | struct GNUNET_FS_AdvertisementContext *ac = cls; | ||
134 | const char *keyword; | ||
135 | GNUNET_HashCode key; | ||
136 | GNUNET_HashCode query; | ||
137 | struct GNUNET_CRYPTO_AesSessionKey skey; | ||
138 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
139 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; | ||
140 | |||
141 | ac->dqe = NULL; | ||
142 | if (GNUNET_SYSERR == success) | ||
143 | { | ||
144 | /* error! */ | ||
145 | (void) GNUNET_SCHEDULER_add_now (&do_disconnect, ac->dsh); | ||
146 | ac->dsh = NULL; | ||
147 | if (msg == NULL) | ||
148 | { | ||
149 | GNUNET_break (0); | ||
150 | msg = _("Unknown error"); | ||
151 | } | ||
152 | if (ac->cont != NULL) | ||
153 | { | ||
154 | ac->cont (ac->cont_cls, NULL, msg); | ||
155 | ac->cont = NULL; | ||
156 | } | ||
157 | GNUNET_FS_namespace_advertise_cancel (ac); | ||
158 | return; | ||
159 | } | ||
160 | if (ac->pos == ac->ksk_uri->data.ksk.keywordCount) | ||
161 | { | ||
162 | /* done! */ | ||
163 | (void) GNUNET_SCHEDULER_add_now (&do_disconnect, ac->dsh); | ||
164 | ac->dsh = NULL; | ||
165 | if (ac->cont != NULL) | ||
166 | { | ||
167 | ac->cont (ac->cont_cls, ac->ksk_uri, NULL); | ||
168 | ac->cont = NULL; | ||
169 | } | ||
170 | GNUNET_FS_namespace_advertise_cancel (ac); | ||
171 | return; | ||
172 | } | ||
173 | keyword = ac->ksk_uri->data.ksk.keywords[ac->pos++]; | ||
174 | /* first character of keyword indicates if it is | ||
175 | * mandatory or not -- ignore for hashing */ | ||
176 | GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); | ||
177 | GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); | ||
178 | GNUNET_CRYPTO_aes_encrypt (ac->pt, ac->pt_size, &skey, &iv, &ac->nb[1]); | ||
179 | GNUNET_break (GNUNET_OK == | ||
180 | GNUNET_CRYPTO_rsa_sign (ac->ns->key, &ac->nb->ns_purpose, | ||
181 | &ac->nb->ns_signature)); | ||
182 | pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); | ||
183 | GNUNET_assert (pk != NULL); | ||
184 | GNUNET_CRYPTO_rsa_key_get_public (pk, &ac->nb->keyspace); | ||
185 | GNUNET_CRYPTO_hash (&ac->nb->keyspace, | ||
186 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
187 | &query); | ||
188 | GNUNET_break (GNUNET_OK == | ||
189 | GNUNET_CRYPTO_rsa_sign (pk, &ac->nb->ksk_purpose, | ||
190 | &ac->nb->ksk_signature)); | ||
191 | GNUNET_CRYPTO_rsa_key_free (pk); | ||
192 | ac->dqe = GNUNET_DATASTORE_put (ac->dsh, 0 /* no reservation */ , | ||
193 | &query, ac->pt_size + sizeof (struct NBlock), ac->nb, | ||
194 | GNUNET_BLOCK_TYPE_FS_NBLOCK, ac->bo.content_priority, | ||
195 | ac->bo.anonymity_level, ac->bo.replication_level, | ||
196 | ac->bo.expiration_time, -2, 1, | ||
197 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &advertisement_cont, | ||
198 | ac); | ||
199 | } | ||
200 | |||
201 | |||
202 | /** | ||
203 | * Publish an advertismement for a namespace. | ||
204 | * | ||
205 | * @param h handle to the file sharing subsystem | ||
206 | * @param ksk_uri keywords to use for advertisment | ||
207 | * @param namespace handle for the namespace that should be advertised | ||
208 | * @param meta meta-data for the namespace advertisement | ||
209 | * @param bo block options | ||
210 | * @param rootEntry name of the root of the namespace | ||
211 | * @param cont continuation | ||
212 | * @param cont_cls closure for cont | ||
213 | * @return NULL on error ('cont' is still called) | ||
214 | */ | ||
215 | struct GNUNET_FS_AdvertisementContext * | ||
216 | GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, | ||
217 | struct GNUNET_FS_Uri *ksk_uri, | ||
218 | struct GNUNET_FS_Namespace *namespace, | ||
219 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
220 | const struct GNUNET_FS_BlockOptions *bo, | ||
221 | const char *rootEntry, | ||
222 | GNUNET_FS_PublishContinuation cont, | ||
223 | void *cont_cls) | ||
224 | { | ||
225 | size_t reslen; | ||
226 | size_t size; | ||
227 | ssize_t mdsize; | ||
228 | struct NBlock *nb; | ||
229 | char *mdst; | ||
230 | struct GNUNET_DATASTORE_Handle *dsh; | ||
231 | struct GNUNET_FS_AdvertisementContext *ctx; | ||
232 | char *pt; | ||
233 | |||
234 | /* create advertisements */ | ||
235 | mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
236 | if (-1 == mdsize) | ||
237 | { | ||
238 | cont (cont_cls, NULL, _("Failed to serialize meta data")); | ||
239 | return NULL; | ||
240 | } | ||
241 | reslen = strlen (rootEntry) + 1; | ||
242 | size = mdsize + sizeof (struct NBlock) + reslen; | ||
243 | if (size > MAX_NBLOCK_SIZE) | ||
244 | { | ||
245 | size = MAX_NBLOCK_SIZE; | ||
246 | mdsize = size - sizeof (struct NBlock) - reslen; | ||
247 | } | ||
248 | |||
249 | pt = GNUNET_malloc (mdsize + reslen); | ||
250 | memcpy (pt, rootEntry, reslen); | ||
251 | mdst = &pt[reslen]; | ||
252 | mdsize = | ||
253 | GNUNET_CONTAINER_meta_data_serialize (meta, &mdst, mdsize, | ||
254 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
255 | if (-1 == mdsize) | ||
256 | { | ||
257 | GNUNET_break (0); | ||
258 | GNUNET_free (pt); | ||
259 | cont (cont_cls, NULL, _("Failed to serialize meta data")); | ||
260 | return NULL; | ||
261 | } | ||
262 | size = mdsize + sizeof (struct NBlock) + reslen; | ||
263 | nb = GNUNET_malloc (size); | ||
264 | GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &nb->subspace); | ||
265 | nb->ns_purpose.size = | ||
266 | htonl (mdsize + reslen + | ||
267 | sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
268 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
269 | nb->ns_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK); | ||
270 | nb->ksk_purpose.size = | ||
271 | htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature)); | ||
272 | nb->ksk_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG); | ||
273 | dsh = GNUNET_DATASTORE_connect (h->cfg); | ||
274 | if (NULL == dsh) | ||
275 | { | ||
276 | GNUNET_free (nb); | ||
277 | GNUNET_free (pt); | ||
278 | cont (cont_cls, NULL, _("Failed to connect to datastore service")); | ||
279 | return NULL; | ||
280 | } | ||
281 | ctx = GNUNET_malloc (sizeof (struct GNUNET_FS_AdvertisementContext)); | ||
282 | ctx->cont = cont; | ||
283 | ctx->cont_cls = cont_cls; | ||
284 | ctx->dsh = dsh; | ||
285 | ctx->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); | ||
286 | ctx->nb = nb; | ||
287 | ctx->pt = pt; | ||
288 | ctx->pt_size = mdsize + reslen; | ||
289 | ctx->ns = namespace; | ||
290 | ctx->ns->rc++; | ||
291 | ctx->bo = *bo; | ||
292 | advertisement_cont (ctx, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); | ||
293 | return ctx; | ||
294 | } | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Abort the namespace advertisement operation. | ||
299 | * | ||
300 | * @param pkc context of the operation to abort. | ||
301 | */ | ||
302 | void | ||
303 | GNUNET_FS_namespace_advertise_cancel (struct GNUNET_FS_AdvertisementContext *ac) | ||
304 | { | ||
305 | if (NULL != ac->dqe) | ||
306 | { | ||
307 | GNUNET_DATASTORE_cancel (ac->dqe); | ||
308 | ac->dqe = NULL; | ||
309 | } | ||
310 | if (NULL != ac->dsh) | ||
311 | { | ||
312 | GNUNET_DATASTORE_disconnect (ac->dsh, GNUNET_NO); | ||
313 | ac->dsh = NULL; | ||
314 | } | ||
315 | GNUNET_FS_uri_destroy (ac->ksk_uri); | ||
316 | GNUNET_free (ac->pt); | ||
317 | GNUNET_free (ac->nb); | ||
318 | GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO); | ||
319 | GNUNET_free (ac); | ||
320 | } | ||
321 | |||
322 | |||
323 | /* end of fs_namespace_advertise.c */ | ||
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 444128016..134dd21e4 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c | |||
@@ -34,13 +34,6 @@ | |||
34 | #include "fs_api.h" | 34 | #include "fs_api.h" |
35 | #include "fs_tree.h" | 35 | #include "fs_tree.h" |
36 | 36 | ||
37 | #define DEBUG_PUBLISH GNUNET_EXTRA_LOGGING | ||
38 | |||
39 | /** | ||
40 | * Maximum legal size for a kblock. | ||
41 | */ | ||
42 | #define MAX_KBLOCK_SIZE (60 * 1024) | ||
43 | |||
44 | 37 | ||
45 | /** | 38 | /** |
46 | * Fill in all of the generic fields for | 39 | * Fill in all of the generic fields for |
@@ -78,17 +71,12 @@ GNUNET_FS_publish_make_status_ (struct GNUNET_FS_ProgressInfo *pi, | |||
78 | /** | 71 | /** |
79 | * Cleanup the publish context, we're done with it. | 72 | * Cleanup the publish context, we're done with it. |
80 | * | 73 | * |
81 | * @param cls struct to clean up after | 74 | * @param pc struct to clean up |
82 | * @param tc scheduler context | ||
83 | */ | 75 | */ |
84 | static void | 76 | static void |
85 | publish_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 77 | publish_cleanup (struct GNUNET_FS_PublishContext *pc) |
86 | { | 78 | { |
87 | struct GNUNET_FS_PublishContext *pc = cls; | ||
88 | |||
89 | #if DEBUG_PUBLISH | ||
90 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up publish context (done!)\n"); | 79 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up publish context (done!)\n"); |
91 | #endif | ||
92 | if (pc->fhc != NULL) | 80 | if (pc->fhc != NULL) |
93 | { | 81 | { |
94 | GNUNET_CRYPTO_hash_file_cancel (pc->fhc); | 82 | GNUNET_CRYPTO_hash_file_cancel (pc->fhc); |
@@ -136,15 +124,6 @@ ds_put_cont (void *cls, int success, | |||
136 | struct GNUNET_FS_ProgressInfo pi; | 124 | struct GNUNET_FS_ProgressInfo pi; |
137 | 125 | ||
138 | pc->qre = NULL; | 126 | pc->qre = NULL; |
139 | if (GNUNET_SYSERR == pc->in_network_wait) | ||
140 | { | ||
141 | /* we were aborted in the meantime, finish shutdown! */ | ||
142 | GNUNET_SCHEDULER_add_continuation (&publish_cleanup, pc, | ||
143 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
144 | return; | ||
145 | } | ||
146 | GNUNET_assert (GNUNET_YES == pc->in_network_wait); | ||
147 | pc->in_network_wait = GNUNET_NO; | ||
148 | if (GNUNET_SYSERR == success) | 127 | if (GNUNET_SYSERR == success) |
149 | { | 128 | { |
150 | GNUNET_asprintf (&pc->fi_pos->emsg, _("Publishing failed: %s"), msg); | 129 | GNUNET_asprintf (&pc->fi_pos->emsg, _("Publishing failed: %s"), msg); |
@@ -238,9 +217,7 @@ finish_release_reserve (void *cls, int success, | |||
238 | struct GNUNET_FS_PublishContext *pc = cls; | 217 | struct GNUNET_FS_PublishContext *pc = cls; |
239 | 218 | ||
240 | pc->qre = NULL; | 219 | pc->qre = NULL; |
241 | #if DEBUG_PUBLISH | ||
242 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Releasing reserve done!\n"); | 220 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Releasing reserve done!\n"); |
243 | #endif | ||
244 | signal_publish_completion (pc->fi, pc); | 221 | signal_publish_completion (pc->fi, pc); |
245 | pc->all_done = GNUNET_YES; | 222 | pc->all_done = GNUNET_YES; |
246 | GNUNET_FS_publish_sync_ (pc); | 223 | GNUNET_FS_publish_sync_ (pc); |
@@ -261,6 +238,7 @@ publish_sblocks_cont (void *cls, const struct GNUNET_FS_Uri *uri, | |||
261 | { | 238 | { |
262 | struct GNUNET_FS_PublishContext *pc = cls; | 239 | struct GNUNET_FS_PublishContext *pc = cls; |
263 | 240 | ||
241 | pc->sks_pc = NULL; | ||
264 | if (NULL != emsg) | 242 | if (NULL != emsg) |
265 | { | 243 | { |
266 | signal_publish_error (pc->fi, pc, emsg); | 244 | signal_publish_error (pc->fi, pc, emsg); |
@@ -292,9 +270,9 @@ static void | |||
292 | publish_sblock (struct GNUNET_FS_PublishContext *pc) | 270 | publish_sblock (struct GNUNET_FS_PublishContext *pc) |
293 | { | 271 | { |
294 | if (NULL != pc->namespace) | 272 | if (NULL != pc->namespace) |
295 | GNUNET_FS_publish_sks (pc->h, pc->namespace, pc->nid, pc->nuid, | 273 | pc->sks_pc = GNUNET_FS_publish_sks (pc->h, pc->namespace, pc->nid, pc->nuid, |
296 | pc->fi->meta, pc->fi->chk_uri, &pc->fi->bo, | 274 | pc->fi->meta, pc->fi->chk_uri, &pc->fi->bo, |
297 | pc->options, &publish_sblocks_cont, pc); | 275 | pc->options, &publish_sblocks_cont, pc); |
298 | else | 276 | else |
299 | publish_sblocks_cont (pc, NULL, NULL); | 277 | publish_sblocks_cont (pc, NULL, NULL); |
300 | } | 278 | } |
@@ -316,25 +294,22 @@ publish_kblocks_cont (void *cls, const struct GNUNET_FS_Uri *uri, | |||
316 | struct GNUNET_FS_PublishContext *pc = cls; | 294 | struct GNUNET_FS_PublishContext *pc = cls; |
317 | struct GNUNET_FS_FileInformation *p = pc->fi_pos; | 295 | struct GNUNET_FS_FileInformation *p = pc->fi_pos; |
318 | 296 | ||
297 | pc->ksk_pc = NULL; | ||
319 | if (NULL != emsg) | 298 | if (NULL != emsg) |
320 | { | 299 | { |
321 | #if DEBUG_PUBLISH | ||
322 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error uploading KSK blocks: %s\n", | 300 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error uploading KSK blocks: %s\n", |
323 | emsg); | 301 | emsg); |
324 | #endif | ||
325 | signal_publish_error (p, pc, emsg); | 302 | signal_publish_error (p, pc, emsg); |
326 | GNUNET_FS_file_information_sync_ (p); | 303 | GNUNET_FS_file_information_sync_ (p); |
327 | GNUNET_FS_publish_sync_ (pc); | 304 | GNUNET_FS_publish_sync_ (pc); |
328 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); | 305 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); |
329 | pc->upload_task = | 306 | pc->upload_task = |
330 | GNUNET_SCHEDULER_add_with_priority | 307 | GNUNET_SCHEDULER_add_with_priority |
331 | (GNUNET_SCHEDULER_PRIORITY_BACKGROUND, &GNUNET_FS_publish_main_, pc); | 308 | (GNUNET_SCHEDULER_PRIORITY_BACKGROUND, &GNUNET_FS_publish_main_, pc); |
332 | return; | 309 | return; |
333 | } | 310 | } |
334 | #if DEBUG_PUBLISH | ||
335 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 311 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
336 | "KSK blocks published, moving on to next file\n"); | 312 | "KSK blocks published, moving on to next file\n"); |
337 | #endif | ||
338 | if (NULL != p->dir) | 313 | if (NULL != p->dir) |
339 | signal_publish_completion (p, pc); | 314 | signal_publish_completion (p, pc); |
340 | /* move on to next file */ | 315 | /* move on to next file */ |
@@ -415,9 +390,7 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
415 | p->te = NULL; | 390 | p->te = NULL; |
416 | if (NULL != emsg) | 391 | if (NULL != emsg) |
417 | { | 392 | { |
418 | #if DEBUG_PUBLISH | ||
419 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error during tree walk: %s\n", emsg); | 393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error during tree walk: %s\n", emsg); |
420 | #endif | ||
421 | GNUNET_asprintf (&p->emsg, _("Publishing failed: %s"), emsg); | 394 | GNUNET_asprintf (&p->emsg, _("Publishing failed: %s"), emsg); |
422 | GNUNET_free (emsg); | 395 | GNUNET_free (emsg); |
423 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; | 396 | pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR; |
@@ -425,9 +398,7 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
425 | pi.value.publish.specifics.error.message = p->emsg; | 398 | pi.value.publish.specifics.error.message = p->emsg; |
426 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0); | 399 | p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0); |
427 | } | 400 | } |
428 | #if DEBUG_PUBLISH | ||
429 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n"); | 401 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n"); |
430 | #endif | ||
431 | /* final progress event */ | 402 | /* final progress event */ |
432 | flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); | 403 | flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); |
433 | pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; | 404 | pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; |
@@ -471,9 +442,7 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, | |||
471 | p = pc->fi_pos; | 442 | p = pc->fi_pos; |
472 | if (NULL == pc->dsh) | 443 | if (NULL == pc->dsh) |
473 | { | 444 | { |
474 | #if DEBUG_PUBLISH | ||
475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Waiting for datastore connection\n"); | 445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Waiting for datastore connection\n"); |
476 | #endif | ||
477 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); | 446 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); |
478 | pc->upload_task = | 447 | pc->upload_task = |
479 | GNUNET_SCHEDULER_add_with_priority | 448 | GNUNET_SCHEDULER_add_with_priority |
@@ -481,17 +450,13 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, | |||
481 | return; | 450 | return; |
482 | } | 451 | } |
483 | 452 | ||
484 | GNUNET_assert (GNUNET_NO == pc->in_network_wait); | ||
485 | pc->in_network_wait = GNUNET_YES; | ||
486 | if ((!p->is_directory) && (GNUNET_YES == p->data.file.do_index) && | 453 | if ((!p->is_directory) && (GNUNET_YES == p->data.file.do_index) && |
487 | (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)) | 454 | (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)) |
488 | { | 455 | { |
489 | #if DEBUG_PUBLISH | ||
490 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 456 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
491 | "Indexing block `%s' for offset %llu with index size %u\n", | 457 | "Indexing block `%s' for offset %llu with index size %u\n", |
492 | GNUNET_h2s (&chk->query), (unsigned long long) offset, | 458 | GNUNET_h2s (&chk->query), (unsigned long long) offset, |
493 | sizeof (struct OnDemandBlock)); | 459 | sizeof (struct OnDemandBlock)); |
494 | #endif | ||
495 | odb.offset = GNUNET_htonll (offset); | 460 | odb.offset = GNUNET_htonll (offset); |
496 | odb.file_id = p->data.file.file_id; | 461 | odb.file_id = p->data.file.file_id; |
497 | GNUNET_assert (pc->qre == NULL); | 462 | GNUNET_assert (pc->qre == NULL); |
@@ -505,12 +470,10 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, | |||
505 | &ds_put_cont, pc); | 470 | &ds_put_cont, pc); |
506 | return; | 471 | return; |
507 | } | 472 | } |
508 | #if DEBUG_PUBLISH | ||
509 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 473 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
510 | "Publishing block `%s' for offset %llu with size %u\n", | 474 | "Publishing block `%s' for offset %llu with size %u\n", |
511 | GNUNET_h2s (&chk->query), (unsigned long long) offset, | 475 | GNUNET_h2s (&chk->query), (unsigned long long) offset, |
512 | (unsigned int) block_size); | 476 | (unsigned int) block_size); |
513 | #endif | ||
514 | GNUNET_assert (pc->qre == NULL); | 477 | GNUNET_assert (pc->qre == NULL); |
515 | pc->qre = | 478 | pc->qre = |
516 | GNUNET_DATASTORE_put (pc->dsh, (p->is_directory) ? 0 : pc->rid, | 479 | GNUNET_DATASTORE_put (pc->dsh, (p->is_directory) ? 0 : pc->rid, |
@@ -573,9 +536,7 @@ publish_content (struct GNUNET_FS_PublishContext *pc) | |||
573 | { | 536 | { |
574 | if (p->is_directory) | 537 | if (p->is_directory) |
575 | { | 538 | { |
576 | #if DEBUG_PUBLISH | ||
577 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating directory\n"); | 539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating directory\n"); |
578 | #endif | ||
579 | db = GNUNET_FS_directory_builder_create (p->meta); | 540 | db = GNUNET_FS_directory_builder_create (p->meta); |
580 | dirpos = p->data.dir.entries; | 541 | dirpos = p->data.dir.entries; |
581 | while (NULL != dirpos) | 542 | while (NULL != dirpos) |
@@ -617,18 +578,14 @@ publish_content (struct GNUNET_FS_PublishContext *pc) | |||
617 | GNUNET_FS_file_information_sync_ (p); | 578 | GNUNET_FS_file_information_sync_ (p); |
618 | } | 579 | } |
619 | size = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size; | 580 | size = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size; |
620 | #if DEBUG_PUBLISH | ||
621 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating tree encoder\n"); | 581 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating tree encoder\n"); |
622 | #endif | ||
623 | p->te = | 582 | p->te = |
624 | GNUNET_FS_tree_encoder_create (pc->h, size, pc, &block_reader, | 583 | GNUNET_FS_tree_encoder_create (pc->h, size, pc, &block_reader, |
625 | &block_proc, &progress_proc, | 584 | &block_proc, &progress_proc, |
626 | &encode_cont); | 585 | &encode_cont); |
627 | 586 | ||
628 | } | 587 | } |
629 | #if DEBUG_PUBLISH | ||
630 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing next block from tree\n"); | 588 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing next block from tree\n"); |
631 | #endif | ||
632 | GNUNET_FS_tree_encoder_next (p->te); | 589 | GNUNET_FS_tree_encoder_next (p->te); |
633 | } | 590 | } |
634 | 591 | ||
@@ -739,10 +696,8 @@ hash_for_index_cb (void *cls, const GNUNET_HashCode * res) | |||
739 | publish_content (pc); | 696 | publish_content (pc); |
740 | return; | 697 | return; |
741 | } | 698 | } |
742 | #if DEBUG_PUBLISH | ||
743 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hash of indexed file `%s' is `%s'\n", | 699 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hash of indexed file `%s' is `%s'\n", |
744 | p->filename, GNUNET_h2s (res)); | 700 | p->filename, GNUNET_h2s (res)); |
745 | #endif | ||
746 | if (0 != (pc->options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | 701 | if (0 != (pc->options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) |
747 | { | 702 | { |
748 | p->data.file.file_id = *res; | 703 | p->data.file.file_id = *res; |
@@ -779,13 +734,11 @@ hash_for_index_cb (void *cls, const GNUNET_HashCode * res) | |||
779 | ism->device = GNUNET_htonll (dev); | 734 | ism->device = GNUNET_htonll (dev); |
780 | ism->inode = GNUNET_htonll (ino); | 735 | ism->inode = GNUNET_htonll (ino); |
781 | } | 736 | } |
782 | #if DEBUG_PUBLISH | ||
783 | else | 737 | else |
784 | { | 738 | { |
785 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 739 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
786 | _("Failed to get file identifiers for `%s'\n"), p->filename); | 740 | _("Failed to get file identifiers for `%s'\n"), p->filename); |
787 | } | 741 | } |
788 | #endif | ||
789 | ism->file_id = *res; | 742 | ism->file_id = *res; |
790 | memcpy (&ism[1], fn, slen); | 743 | memcpy (&ism[1], fn, slen); |
791 | GNUNET_free (fn); | 744 | GNUNET_free (fn); |
@@ -820,10 +773,8 @@ GNUNET_FS_publish_main_ (void *cls, | |||
820 | p = pc->fi_pos; | 773 | p = pc->fi_pos; |
821 | if (NULL == p) | 774 | if (NULL == p) |
822 | { | 775 | { |
823 | #if DEBUG_PUBLISH | ||
824 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 776 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
825 | "Publishing complete, now publishing SKS and KSK blocks.\n"); | 777 | "Publishing complete, now publishing SKS and KSK blocks.\n"); |
826 | #endif | ||
827 | /* upload of entire hierarchy complete, | 778 | /* upload of entire hierarchy complete, |
828 | * publish namespace entries */ | 779 | * publish namespace entries */ |
829 | GNUNET_FS_publish_sync_ (pc); | 780 | GNUNET_FS_publish_sync_ (pc); |
@@ -841,9 +792,7 @@ GNUNET_FS_publish_main_ (void *cls, | |||
841 | /* abort on error */ | 792 | /* abort on error */ |
842 | if (NULL != p->emsg) | 793 | if (NULL != p->emsg) |
843 | { | 794 | { |
844 | #if DEBUG_PUBLISH | ||
845 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error uploading: %s\n", p->emsg); | 795 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error uploading: %s\n", p->emsg); |
846 | #endif | ||
847 | /* error with current file, abort all | 796 | /* error with current file, abort all |
848 | * related files as well! */ | 797 | * related files as well! */ |
849 | while (NULL != p->dir) | 798 | while (NULL != p->dir) |
@@ -873,10 +822,8 @@ GNUNET_FS_publish_main_ (void *cls, | |||
873 | /* handle completion */ | 822 | /* handle completion */ |
874 | if (NULL != p->chk_uri) | 823 | if (NULL != p->chk_uri) |
875 | { | 824 | { |
876 | #if DEBUG_PUBLISH | ||
877 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 825 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
878 | "File upload complete, now publishing KSK blocks.\n"); | 826 | "File upload complete, now publishing KSK blocks.\n"); |
879 | #endif | ||
880 | if (0 == p->bo.anonymity_level) | 827 | if (0 == p->bo.anonymity_level) |
881 | { | 828 | { |
882 | /* zero anonymity, box CHK URI in LOC URI */ | 829 | /* zero anonymity, box CHK URI in LOC URI */ |
@@ -890,8 +837,8 @@ GNUNET_FS_publish_main_ (void *cls, | |||
890 | /* upload of "p" complete, publish KBlocks! */ | 837 | /* upload of "p" complete, publish KBlocks! */ |
891 | if (p->keywords != NULL) | 838 | if (p->keywords != NULL) |
892 | { | 839 | { |
893 | GNUNET_FS_publish_ksk (pc->h, p->keywords, p->meta, p->chk_uri, &p->bo, | 840 | pc->ksk_pc = GNUNET_FS_publish_ksk (pc->h, p->keywords, p->meta, p->chk_uri, &p->bo, |
894 | pc->options, &publish_kblocks_cont, pc); | 841 | pc->options, &publish_kblocks_cont, pc); |
895 | } | 842 | } |
896 | else | 843 | else |
897 | { | 844 | { |
@@ -959,9 +906,7 @@ fip_signal_start (void *cls, struct GNUNET_FS_FileInformation *fi, | |||
959 | pc->skip_next_fi_callback = GNUNET_NO; | 906 | pc->skip_next_fi_callback = GNUNET_NO; |
960 | return GNUNET_OK; | 907 | return GNUNET_OK; |
961 | } | 908 | } |
962 | #if DEBUG_PUBLISH | ||
963 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting publish operation\n"); | 909 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting publish operation\n"); |
964 | #endif | ||
965 | if (*do_index) | 910 | if (*do_index) |
966 | { | 911 | { |
967 | /* space for on-demand blocks */ | 912 | /* space for on-demand blocks */ |
@@ -1043,9 +988,17 @@ fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, | |||
1043 | pc->skip_next_fi_callback = GNUNET_YES; | 988 | pc->skip_next_fi_callback = GNUNET_YES; |
1044 | GNUNET_FS_file_information_inspect (fi, &fip_signal_suspend, pc); | 989 | GNUNET_FS_file_information_inspect (fi, &fip_signal_suspend, pc); |
1045 | } | 990 | } |
1046 | #if DEBUG_PUBLISH | 991 | if (NULL != pc->ksk_pc) |
992 | { | ||
993 | GNUNET_FS_publish_ksk_cancel (pc->ksk_pc); | ||
994 | pc->ksk_pc = NULL; | ||
995 | } | ||
996 | if (NULL != pc->sks_pc) | ||
997 | { | ||
998 | GNUNET_FS_publish_sks_cancel (pc->sks_pc); | ||
999 | pc->sks_pc = NULL; | ||
1000 | } | ||
1047 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending publish operation\n"); | 1001 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending publish operation\n"); |
1048 | #endif | ||
1049 | GNUNET_free_non_null (fi->serialization); | 1002 | GNUNET_free_non_null (fi->serialization); |
1050 | fi->serialization = NULL; | 1003 | fi->serialization = NULL; |
1051 | off = (fi->chk_uri == NULL) ? 0 : length; | 1004 | off = (fi->chk_uri == NULL) ? 0 : length; |
@@ -1086,7 +1039,7 @@ GNUNET_FS_publish_signal_suspend_ (void *cls) | |||
1086 | GNUNET_FS_file_information_inspect (pc->fi, &fip_signal_suspend, pc); | 1039 | GNUNET_FS_file_information_inspect (pc->fi, &fip_signal_suspend, pc); |
1087 | GNUNET_FS_end_top (pc->h, pc->top); | 1040 | GNUNET_FS_end_top (pc->h, pc->top); |
1088 | pc->top = NULL; | 1041 | pc->top = NULL; |
1089 | publish_cleanup (pc, NULL); | 1042 | publish_cleanup (pc); |
1090 | } | 1043 | } |
1091 | 1044 | ||
1092 | 1045 | ||
@@ -1107,9 +1060,7 @@ finish_reserve (void *cls, int success, | |||
1107 | struct GNUNET_FS_PublishContext *pc = cls; | 1060 | struct GNUNET_FS_PublishContext *pc = cls; |
1108 | 1061 | ||
1109 | pc->qre = NULL; | 1062 | pc->qre = NULL; |
1110 | #if DEBUG_PUBLISH | ||
1111 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reservation complete (%d)!\n", success); | 1063 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reservation complete (%d)!\n", success); |
1112 | #endif | ||
1113 | if ((msg != NULL) || (success <= 0)) | 1064 | if ((msg != NULL) || (success <= 0)) |
1114 | { | 1065 | { |
1115 | GNUNET_asprintf (&pc->fi->emsg, _("Insufficient space for publishing: %s"), | 1066 | GNUNET_asprintf (&pc->fi->emsg, _("Insufficient space for publishing: %s"), |
@@ -1267,14 +1218,17 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc) | |||
1267 | struct GNUNET_FS_ProgressInfo pi; | 1218 | struct GNUNET_FS_ProgressInfo pi; |
1268 | uint64_t off; | 1219 | uint64_t off; |
1269 | 1220 | ||
1270 | #if DEBUG_PUBLISH | ||
1271 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publish stop called\n"); | 1221 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publish stop called\n"); |
1272 | #endif | ||
1273 | GNUNET_FS_end_top (pc->h, pc->top); | 1222 | GNUNET_FS_end_top (pc->h, pc->top); |
1274 | if (NULL != pc->qre) | 1223 | if (NULL != pc->ksk_pc) |
1275 | { | 1224 | { |
1276 | GNUNET_DATASTORE_cancel (pc->qre); | 1225 | GNUNET_FS_publish_ksk_cancel (pc->ksk_pc); |
1277 | pc->qre = NULL; | 1226 | pc->ksk_pc = NULL; |
1227 | } | ||
1228 | if (NULL != pc->sks_pc) | ||
1229 | { | ||
1230 | GNUNET_FS_publish_sks_cancel (pc->sks_pc); | ||
1231 | pc->sks_pc = NULL; | ||
1278 | } | 1232 | } |
1279 | if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task) | 1233 | if (GNUNET_SCHEDULER_NO_TASK != pc->upload_task) |
1280 | { | 1234 | { |
@@ -1300,299 +1254,16 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc) | |||
1300 | GNUNET_free (pc->serialization); | 1254 | GNUNET_free (pc->serialization); |
1301 | pc->serialization = NULL; | 1255 | pc->serialization = NULL; |
1302 | } | 1256 | } |
1303 | if (GNUNET_YES == pc->in_network_wait) | 1257 | if (NULL != pc->qre) |
1304 | { | 1258 | { |
1305 | pc->in_network_wait = GNUNET_SYSERR; | 1259 | GNUNET_DATASTORE_cancel (pc->qre); |
1306 | return; | 1260 | pc->qre = NULL; |
1307 | } | 1261 | } |
1308 | pi.status = GNUNET_FS_STATUS_PUBLISH_STOPPED; | 1262 | pi.status = GNUNET_FS_STATUS_PUBLISH_STOPPED; |
1309 | GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, pc, pc->fi, off)); | 1263 | GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, pc, pc->fi, off)); |
1310 | publish_cleanup (pc, NULL); | 1264 | publish_cleanup (pc); |
1311 | } | 1265 | } |
1312 | 1266 | ||
1313 | 1267 | ||
1314 | /** | ||
1315 | * Context for the KSK publication. | ||
1316 | */ | ||
1317 | struct PublishKskContext | ||
1318 | { | ||
1319 | |||
1320 | /** | ||
1321 | * Keywords to use. | ||
1322 | */ | ||
1323 | struct GNUNET_FS_Uri *ksk_uri; | ||
1324 | |||
1325 | /** | ||
1326 | * Global FS context. | ||
1327 | */ | ||
1328 | struct GNUNET_FS_Handle *h; | ||
1329 | |||
1330 | /** | ||
1331 | * The master block that we are sending | ||
1332 | * (in plaintext), has "mdsize+slen" more | ||
1333 | * bytes than the struct would suggest. | ||
1334 | */ | ||
1335 | struct KBlock *kb; | ||
1336 | |||
1337 | /** | ||
1338 | * Buffer of the same size as "kb" for | ||
1339 | * the encrypted version. | ||
1340 | */ | ||
1341 | struct KBlock *cpy; | ||
1342 | |||
1343 | /** | ||
1344 | * Handle to the datastore, NULL if we are just | ||
1345 | * simulating. | ||
1346 | */ | ||
1347 | struct GNUNET_DATASTORE_Handle *dsh; | ||
1348 | |||
1349 | /** | ||
1350 | * Handle to datastore PUT request. | ||
1351 | */ | ||
1352 | struct GNUNET_DATASTORE_QueueEntry *qre; | ||
1353 | |||
1354 | /** | ||
1355 | * Function to call once we're done. | ||
1356 | */ | ||
1357 | GNUNET_FS_PublishContinuation cont; | ||
1358 | |||
1359 | /** | ||
1360 | * Closure for cont. | ||
1361 | */ | ||
1362 | void *cont_cls; | ||
1363 | |||
1364 | /** | ||
1365 | * When should the KBlocks expire? | ||
1366 | */ | ||
1367 | struct GNUNET_FS_BlockOptions bo; | ||
1368 | |||
1369 | /** | ||
1370 | * Size of the serialized metadata. | ||
1371 | */ | ||
1372 | ssize_t mdsize; | ||
1373 | |||
1374 | /** | ||
1375 | * Size of the (CHK) URI as a string. | ||
1376 | */ | ||
1377 | size_t slen; | ||
1378 | |||
1379 | /** | ||
1380 | * Keyword that we are currently processing. | ||
1381 | */ | ||
1382 | unsigned int i; | ||
1383 | |||
1384 | }; | ||
1385 | |||
1386 | |||
1387 | /** | ||
1388 | * Continuation of "GNUNET_FS_publish_ksk" that performs | ||
1389 | * the actual publishing operation (iterating over all | ||
1390 | * of the keywords). | ||
1391 | * | ||
1392 | * @param cls closure of type "struct PublishKskContext*" | ||
1393 | * @param tc unused | ||
1394 | */ | ||
1395 | static void | ||
1396 | publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
1397 | |||
1398 | |||
1399 | /** | ||
1400 | * Function called by the datastore API with | ||
1401 | * the result from the PUT request. | ||
1402 | * | ||
1403 | * @param cls closure of type "struct PublishKskContext*" | ||
1404 | * @param success GNUNET_OK on success | ||
1405 | * @param min_expiration minimum expiration time required for content to be stored | ||
1406 | * @param msg error message (or NULL) | ||
1407 | */ | ||
1408 | static void | ||
1409 | kb_put_cont (void *cls, int success, | ||
1410 | struct GNUNET_TIME_Absolute min_expiration, | ||
1411 | const char *msg) | ||
1412 | { | ||
1413 | struct PublishKskContext *pkc = cls; | ||
1414 | |||
1415 | pkc->qre = NULL; | ||
1416 | if (GNUNET_OK != success) | ||
1417 | { | ||
1418 | #if DEBUG_PUBLISH | ||
1419 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KB PUT operation complete\n"); | ||
1420 | #endif | ||
1421 | if (NULL != pkc->dsh) | ||
1422 | { | ||
1423 | GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); | ||
1424 | pkc->dsh = NULL; | ||
1425 | } | ||
1426 | GNUNET_free (pkc->cpy); | ||
1427 | GNUNET_free (pkc->kb); | ||
1428 | pkc->cont (pkc->cont_cls, NULL, msg); | ||
1429 | GNUNET_FS_uri_destroy (pkc->ksk_uri); | ||
1430 | GNUNET_free (pkc); | ||
1431 | return; | ||
1432 | } | ||
1433 | GNUNET_SCHEDULER_add_continuation (&publish_ksk_cont, pkc, | ||
1434 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
1435 | } | ||
1436 | |||
1437 | |||
1438 | /** | ||
1439 | * Continuation of "GNUNET_FS_publish_ksk" that performs the actual | ||
1440 | * publishing operation (iterating over all of the keywords). | ||
1441 | * | ||
1442 | * @param cls closure of type "struct PublishKskContext*" | ||
1443 | * @param tc unused | ||
1444 | */ | ||
1445 | static void | ||
1446 | publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1447 | { | ||
1448 | struct PublishKskContext *pkc = cls; | ||
1449 | const char *keyword; | ||
1450 | GNUNET_HashCode key; | ||
1451 | GNUNET_HashCode query; | ||
1452 | struct GNUNET_CRYPTO_AesSessionKey skey; | ||
1453 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
1454 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; | ||
1455 | |||
1456 | |||
1457 | if ((pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || (NULL == pkc->dsh)) | ||
1458 | { | ||
1459 | #if DEBUG_PUBLISH | ||
1460 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KSK PUT operation complete\n"); | ||
1461 | #endif | ||
1462 | if (NULL != pkc->dsh) | ||
1463 | { | ||
1464 | GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); | ||
1465 | pkc->dsh = NULL; | ||
1466 | } | ||
1467 | GNUNET_free (pkc->cpy); | ||
1468 | GNUNET_free (pkc->kb); | ||
1469 | pkc->cont (pkc->cont_cls, pkc->ksk_uri, NULL); | ||
1470 | GNUNET_FS_uri_destroy (pkc->ksk_uri); | ||
1471 | GNUNET_free (pkc); | ||
1472 | return; | ||
1473 | } | ||
1474 | keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; | ||
1475 | #if DEBUG_PUBLISH | ||
1476 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n", | ||
1477 | keyword); | ||
1478 | #endif | ||
1479 | /* first character of keyword indicates if it is | ||
1480 | * mandatory or not -- ignore for hashing */ | ||
1481 | GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); | ||
1482 | GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); | ||
1483 | GNUNET_CRYPTO_aes_encrypt (&pkc->kb[1], pkc->slen + pkc->mdsize, &skey, &iv, | ||
1484 | &pkc->cpy[1]); | ||
1485 | pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); | ||
1486 | GNUNET_assert (NULL != pk); | ||
1487 | GNUNET_CRYPTO_rsa_key_get_public (pk, &pkc->cpy->keyspace); | ||
1488 | GNUNET_CRYPTO_hash (&pkc->cpy->keyspace, | ||
1489 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
1490 | &query); | ||
1491 | GNUNET_assert (GNUNET_OK == | ||
1492 | GNUNET_CRYPTO_rsa_sign (pk, &pkc->cpy->purpose, | ||
1493 | &pkc->cpy->signature)); | ||
1494 | GNUNET_CRYPTO_rsa_key_free (pk); | ||
1495 | pkc->qre = | ||
1496 | GNUNET_DATASTORE_put (pkc->dsh, 0, &query, | ||
1497 | pkc->mdsize + sizeof (struct KBlock) + pkc->slen, | ||
1498 | pkc->cpy, GNUNET_BLOCK_TYPE_FS_KBLOCK, | ||
1499 | pkc->bo.content_priority, pkc->bo.anonymity_level, | ||
1500 | pkc->bo.replication_level, pkc->bo.expiration_time, | ||
1501 | -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
1502 | &kb_put_cont, pkc); | ||
1503 | } | ||
1504 | |||
1505 | |||
1506 | /** | ||
1507 | * Publish a CHK under various keywords on GNUnet. | ||
1508 | * | ||
1509 | * @param h handle to the file sharing subsystem | ||
1510 | * @param ksk_uri keywords to use | ||
1511 | * @param meta metadata to use | ||
1512 | * @param uri URI to refer to in the KBlock | ||
1513 | * @param bo per-block options | ||
1514 | * @param options publication options | ||
1515 | * @param cont continuation | ||
1516 | * @param cont_cls closure for cont | ||
1517 | */ | ||
1518 | void | ||
1519 | GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, | ||
1520 | const struct GNUNET_FS_Uri *ksk_uri, | ||
1521 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
1522 | const struct GNUNET_FS_Uri *uri, | ||
1523 | const struct GNUNET_FS_BlockOptions *bo, | ||
1524 | enum GNUNET_FS_PublishOptions options, | ||
1525 | GNUNET_FS_PublishContinuation cont, void *cont_cls) | ||
1526 | { | ||
1527 | struct PublishKskContext *pkc; | ||
1528 | char *uris; | ||
1529 | size_t size; | ||
1530 | char *kbe; | ||
1531 | char *sptr; | ||
1532 | |||
1533 | GNUNET_assert (NULL != uri); | ||
1534 | pkc = GNUNET_malloc (sizeof (struct PublishKskContext)); | ||
1535 | pkc->h = h; | ||
1536 | pkc->bo = *bo; | ||
1537 | pkc->cont = cont; | ||
1538 | pkc->cont_cls = cont_cls; | ||
1539 | if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | ||
1540 | { | ||
1541 | pkc->dsh = GNUNET_DATASTORE_connect (h->cfg); | ||
1542 | if (pkc->dsh == NULL) | ||
1543 | { | ||
1544 | cont (cont_cls, NULL, _("Could not connect to datastore.")); | ||
1545 | GNUNET_free (pkc); | ||
1546 | return; | ||
1547 | } | ||
1548 | } | ||
1549 | if (meta == NULL) | ||
1550 | pkc->mdsize = 0; | ||
1551 | else | ||
1552 | pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
1553 | GNUNET_assert (pkc->mdsize >= 0); | ||
1554 | uris = GNUNET_FS_uri_to_string (uri); | ||
1555 | pkc->slen = strlen (uris) + 1; | ||
1556 | size = pkc->mdsize + sizeof (struct KBlock) + pkc->slen; | ||
1557 | if (size > MAX_KBLOCK_SIZE) | ||
1558 | { | ||
1559 | size = MAX_KBLOCK_SIZE; | ||
1560 | pkc->mdsize = size - sizeof (struct KBlock) - pkc->slen; | ||
1561 | } | ||
1562 | pkc->kb = GNUNET_malloc (size); | ||
1563 | kbe = (char *) &pkc->kb[1]; | ||
1564 | memcpy (kbe, uris, pkc->slen); | ||
1565 | GNUNET_free (uris); | ||
1566 | sptr = &kbe[pkc->slen]; | ||
1567 | if (meta != NULL) | ||
1568 | pkc->mdsize = | ||
1569 | GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, pkc->mdsize, | ||
1570 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
1571 | if (pkc->mdsize == -1) | ||
1572 | { | ||
1573 | GNUNET_break (0); | ||
1574 | GNUNET_free (pkc->kb); | ||
1575 | if (pkc->dsh != NULL) | ||
1576 | { | ||
1577 | GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); | ||
1578 | pkc->dsh = NULL; | ||
1579 | } | ||
1580 | cont (cont_cls, NULL, _("Internal error.")); | ||
1581 | GNUNET_free (pkc); | ||
1582 | return; | ||
1583 | } | ||
1584 | size = sizeof (struct KBlock) + pkc->slen + pkc->mdsize; | ||
1585 | |||
1586 | pkc->cpy = GNUNET_malloc (size); | ||
1587 | pkc->cpy->purpose.size = | ||
1588 | htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
1589 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + | ||
1590 | pkc->mdsize + pkc->slen); | ||
1591 | pkc->cpy->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK); | ||
1592 | pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); | ||
1593 | GNUNET_SCHEDULER_add_continuation (&publish_ksk_cont, pkc, | ||
1594 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
1595 | } | ||
1596 | |||
1597 | 1268 | ||
1598 | /* end of fs_publish.c */ | 1269 | /* end of fs_publish.c */ |
diff --git a/src/fs/fs_publish_ksk.c b/src/fs/fs_publish_ksk.c new file mode 100644 index 000000000..5119de4c5 --- /dev/null +++ b/src/fs/fs_publish_ksk.c | |||
@@ -0,0 +1,342 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009, 2010, 2012 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 3, 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_publish_ksk.c | ||
23 | * @brief publish a URI under a keyword in GNUnet | ||
24 | * @see https://gnunet.org/encoding | ||
25 | * @author Krista Bennett | ||
26 | * @author Christian Grothoff | ||
27 | */ | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_constants.h" | ||
31 | #include "gnunet_signatures.h" | ||
32 | #include "gnunet_util_lib.h" | ||
33 | #include "gnunet_fs_service.h" | ||
34 | #include "fs_api.h" | ||
35 | #include "fs_tree.h" | ||
36 | |||
37 | |||
38 | /** | ||
39 | * Maximum legal size for a kblock. | ||
40 | */ | ||
41 | #define MAX_KBLOCK_SIZE (60 * 1024) | ||
42 | |||
43 | |||
44 | /** | ||
45 | * Context for the KSK publication. | ||
46 | */ | ||
47 | struct GNUNET_FS_PublishKskContext | ||
48 | { | ||
49 | |||
50 | /** | ||
51 | * Keywords to use. | ||
52 | */ | ||
53 | struct GNUNET_FS_Uri *ksk_uri; | ||
54 | |||
55 | /** | ||
56 | * Global FS context. | ||
57 | */ | ||
58 | struct GNUNET_FS_Handle *h; | ||
59 | |||
60 | /** | ||
61 | * The master block that we are sending | ||
62 | * (in plaintext), has "mdsize+slen" more | ||
63 | * bytes than the struct would suggest. | ||
64 | */ | ||
65 | struct KBlock *kb; | ||
66 | |||
67 | /** | ||
68 | * Buffer of the same size as "kb" for | ||
69 | * the encrypted version. | ||
70 | */ | ||
71 | struct KBlock *cpy; | ||
72 | |||
73 | /** | ||
74 | * Handle to the datastore, NULL if we are just | ||
75 | * simulating. | ||
76 | */ | ||
77 | struct GNUNET_DATASTORE_Handle *dsh; | ||
78 | |||
79 | /** | ||
80 | * Handle to datastore PUT request. | ||
81 | */ | ||
82 | struct GNUNET_DATASTORE_QueueEntry *qre; | ||
83 | |||
84 | /** | ||
85 | * Current task. | ||
86 | */ | ||
87 | GNUNET_SCHEDULER_TaskIdentifier ksk_task; | ||
88 | |||
89 | /** | ||
90 | * Function to call once we're done. | ||
91 | */ | ||
92 | GNUNET_FS_PublishContinuation cont; | ||
93 | |||
94 | /** | ||
95 | * Closure for cont. | ||
96 | */ | ||
97 | void *cont_cls; | ||
98 | |||
99 | /** | ||
100 | * When should the KBlocks expire? | ||
101 | */ | ||
102 | struct GNUNET_FS_BlockOptions bo; | ||
103 | |||
104 | /** | ||
105 | * Size of the serialized metadata. | ||
106 | */ | ||
107 | ssize_t mdsize; | ||
108 | |||
109 | /** | ||
110 | * Size of the (CHK) URI as a string. | ||
111 | */ | ||
112 | size_t slen; | ||
113 | |||
114 | /** | ||
115 | * Keyword that we are currently processing. | ||
116 | */ | ||
117 | unsigned int i; | ||
118 | |||
119 | }; | ||
120 | |||
121 | |||
122 | /** | ||
123 | * Continuation of "GNUNET_FS_publish_ksk" that performs | ||
124 | * the actual publishing operation (iterating over all | ||
125 | * of the keywords). | ||
126 | * | ||
127 | * @param cls closure of type "struct PublishKskContext*" | ||
128 | * @param tc unused | ||
129 | */ | ||
130 | static void | ||
131 | publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
132 | |||
133 | |||
134 | /** | ||
135 | * Function called by the datastore API with | ||
136 | * the result from the PUT request. | ||
137 | * | ||
138 | * @param cls closure of type "struct GNUNET_FS_PublishKskContext*" | ||
139 | * @param success GNUNET_OK on success | ||
140 | * @param min_expiration minimum expiration time required for content to be stored | ||
141 | * @param msg error message (or NULL) | ||
142 | */ | ||
143 | static void | ||
144 | kb_put_cont (void *cls, int success, | ||
145 | struct GNUNET_TIME_Absolute min_expiration, | ||
146 | const char *msg) | ||
147 | { | ||
148 | struct GNUNET_FS_PublishKskContext *pkc = cls; | ||
149 | |||
150 | pkc->qre = NULL; | ||
151 | if (GNUNET_OK != success) | ||
152 | { | ||
153 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
154 | "KBlock PUT operation failed: %s\n", msg); | ||
155 | pkc->cont (pkc->cont_cls, NULL, msg); | ||
156 | GNUNET_FS_publish_ksk_cancel (pkc); | ||
157 | return; | ||
158 | } | ||
159 | pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc); | ||
160 | } | ||
161 | |||
162 | |||
163 | /** | ||
164 | * Continuation of "GNUNET_FS_publish_ksk" that performs the actual | ||
165 | * publishing operation (iterating over all of the keywords). | ||
166 | * | ||
167 | * @param cls closure of type "struct GNUNET_FS_PublishKskContext*" | ||
168 | * @param tc unused | ||
169 | */ | ||
170 | static void | ||
171 | publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
172 | { | ||
173 | struct GNUNET_FS_PublishKskContext *pkc = cls; | ||
174 | const char *keyword; | ||
175 | GNUNET_HashCode key; | ||
176 | GNUNET_HashCode query; | ||
177 | struct GNUNET_CRYPTO_AesSessionKey skey; | ||
178 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
179 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; | ||
180 | |||
181 | pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; | ||
182 | if ((pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || (NULL == pkc->dsh)) | ||
183 | { | ||
184 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KSK PUT operation complete\n"); | ||
185 | pkc->cont (pkc->cont_cls, pkc->ksk_uri, NULL); | ||
186 | GNUNET_FS_publish_ksk_cancel (pkc); | ||
187 | return; | ||
188 | } | ||
189 | keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; | ||
190 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n", | ||
191 | keyword); | ||
192 | /* first character of keyword indicates if it is | ||
193 | * mandatory or not -- ignore for hashing */ | ||
194 | GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); | ||
195 | GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); | ||
196 | GNUNET_CRYPTO_aes_encrypt (&pkc->kb[1], pkc->slen + pkc->mdsize, &skey, &iv, | ||
197 | &pkc->cpy[1]); | ||
198 | pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); | ||
199 | GNUNET_assert (NULL != pk); | ||
200 | GNUNET_CRYPTO_rsa_key_get_public (pk, &pkc->cpy->keyspace); | ||
201 | GNUNET_CRYPTO_hash (&pkc->cpy->keyspace, | ||
202 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
203 | &query); | ||
204 | GNUNET_assert (GNUNET_OK == | ||
205 | GNUNET_CRYPTO_rsa_sign (pk, &pkc->cpy->purpose, | ||
206 | &pkc->cpy->signature)); | ||
207 | GNUNET_CRYPTO_rsa_key_free (pk); | ||
208 | pkc->qre = | ||
209 | GNUNET_DATASTORE_put (pkc->dsh, 0, &query, | ||
210 | pkc->mdsize + sizeof (struct KBlock) + pkc->slen, | ||
211 | pkc->cpy, GNUNET_BLOCK_TYPE_FS_KBLOCK, | ||
212 | pkc->bo.content_priority, pkc->bo.anonymity_level, | ||
213 | pkc->bo.replication_level, pkc->bo.expiration_time, | ||
214 | -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
215 | &kb_put_cont, pkc); | ||
216 | } | ||
217 | |||
218 | |||
219 | /** | ||
220 | * Publish a CHK under various keywords on GNUnet. | ||
221 | * | ||
222 | * @param h handle to the file sharing subsystem | ||
223 | * @param ksk_uri keywords to use | ||
224 | * @param meta metadata to use | ||
225 | * @param uri URI to refer to in the KBlock | ||
226 | * @param bo per-block options | ||
227 | * @param options publication options | ||
228 | * @param cont continuation | ||
229 | * @param cont_cls closure for cont | ||
230 | * @return NULL on error ('cont' will still be called) | ||
231 | */ | ||
232 | struct GNUNET_FS_PublishKskContext * | ||
233 | GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, | ||
234 | const struct GNUNET_FS_Uri *ksk_uri, | ||
235 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
236 | const struct GNUNET_FS_Uri *uri, | ||
237 | const struct GNUNET_FS_BlockOptions *bo, | ||
238 | enum GNUNET_FS_PublishOptions options, | ||
239 | GNUNET_FS_PublishContinuation cont, void *cont_cls) | ||
240 | { | ||
241 | struct GNUNET_FS_PublishKskContext *pkc; | ||
242 | char *uris; | ||
243 | size_t size; | ||
244 | char *kbe; | ||
245 | char *sptr; | ||
246 | |||
247 | GNUNET_assert (NULL != uri); | ||
248 | pkc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishKskContext)); | ||
249 | pkc->h = h; | ||
250 | pkc->bo = *bo; | ||
251 | pkc->cont = cont; | ||
252 | pkc->cont_cls = cont_cls; | ||
253 | if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | ||
254 | { | ||
255 | pkc->dsh = GNUNET_DATASTORE_connect (h->cfg); | ||
256 | if (NULL == pkc->dsh) | ||
257 | { | ||
258 | cont (cont_cls, NULL, _("Could not connect to datastore.")); | ||
259 | GNUNET_free (pkc); | ||
260 | return NULL; | ||
261 | } | ||
262 | } | ||
263 | if (meta == NULL) | ||
264 | pkc->mdsize = 0; | ||
265 | else | ||
266 | pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
267 | GNUNET_assert (pkc->mdsize >= 0); | ||
268 | uris = GNUNET_FS_uri_to_string (uri); | ||
269 | pkc->slen = strlen (uris) + 1; | ||
270 | size = pkc->mdsize + sizeof (struct KBlock) + pkc->slen; | ||
271 | if (size > MAX_KBLOCK_SIZE) | ||
272 | { | ||
273 | size = MAX_KBLOCK_SIZE; | ||
274 | pkc->mdsize = size - sizeof (struct KBlock) - pkc->slen; | ||
275 | } | ||
276 | pkc->kb = GNUNET_malloc (size); | ||
277 | kbe = (char *) &pkc->kb[1]; | ||
278 | memcpy (kbe, uris, pkc->slen); | ||
279 | GNUNET_free (uris); | ||
280 | sptr = &kbe[pkc->slen]; | ||
281 | if (meta != NULL) | ||
282 | pkc->mdsize = | ||
283 | GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, pkc->mdsize, | ||
284 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
285 | if (-1 == pkc->mdsize) | ||
286 | { | ||
287 | GNUNET_break (0); | ||
288 | GNUNET_free (pkc->kb); | ||
289 | if (pkc->dsh != NULL) | ||
290 | { | ||
291 | GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); | ||
292 | pkc->dsh = NULL; | ||
293 | } | ||
294 | GNUNET_free (pkc); | ||
295 | cont (cont_cls, NULL, _("Internal error.")); | ||
296 | return NULL; | ||
297 | } | ||
298 | size = sizeof (struct KBlock) + pkc->slen + pkc->mdsize; | ||
299 | |||
300 | pkc->cpy = GNUNET_malloc (size); | ||
301 | pkc->cpy->purpose.size = | ||
302 | htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
303 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + | ||
304 | pkc->mdsize + pkc->slen); | ||
305 | pkc->cpy->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK); | ||
306 | pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); | ||
307 | pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc); | ||
308 | return pkc; | ||
309 | } | ||
310 | |||
311 | |||
312 | /** | ||
313 | * Abort the KSK publishing operation. | ||
314 | * | ||
315 | * @param pkc context of the operation to abort. | ||
316 | */ | ||
317 | void | ||
318 | GNUNET_FS_publish_ksk_cancel (struct GNUNET_FS_PublishKskContext *pkc) | ||
319 | { | ||
320 | if (GNUNET_SCHEDULER_NO_TASK != pkc->ksk_task) | ||
321 | { | ||
322 | GNUNET_SCHEDULER_cancel (pkc->ksk_task); | ||
323 | pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; | ||
324 | } | ||
325 | if (NULL != pkc->qre) | ||
326 | { | ||
327 | GNUNET_DATASTORE_cancel (pkc->qre); | ||
328 | pkc->qre = NULL; | ||
329 | } | ||
330 | if (NULL != pkc->dsh) | ||
331 | { | ||
332 | GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); | ||
333 | pkc->dsh = NULL; | ||
334 | } | ||
335 | GNUNET_free (pkc->cpy); | ||
336 | GNUNET_free (pkc->kb); | ||
337 | GNUNET_FS_uri_destroy (pkc->ksk_uri); | ||
338 | GNUNET_free (pkc); | ||
339 | } | ||
340 | |||
341 | |||
342 | /* end of fs_publish_ksk.c */ | ||
diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c index fc04446c9..2ac38ffd3 100644 --- a/src/fs/fs_tree.c +++ b/src/fs/fs_tree.c | |||
@@ -360,8 +360,7 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te) | |||
360 | if (pt_size != | 360 | if (pt_size != |
361 | te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg)) | 361 | te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg)) |
362 | { | 362 | { |
363 | GNUNET_SCHEDULER_add_continuation (te->cont, te->cls, | 363 | te->cont (te->cls, NULL); |
364 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
365 | te->in_next = GNUNET_NO; | 364 | te->in_next = GNUNET_NO; |
366 | return; | 365 | return; |
367 | } | 366 | } |
diff --git a/src/fs/gnunet-fs.c b/src/fs/gnunet-fs.c index 8cf08ec28..0b2892371 100644 --- a/src/fs/gnunet-fs.c +++ b/src/fs/gnunet-fs.c | |||
@@ -47,20 +47,6 @@ static int verbose; | |||
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Shutdown this process. | ||
51 | * | ||
52 | * @param cls unused | ||
53 | * @param tc unused | ||
54 | */ | ||
55 | static void | ||
56 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
57 | { | ||
58 | GNUNET_FS_stop (fs); | ||
59 | fs = NULL; | ||
60 | } | ||
61 | |||
62 | |||
63 | /** | ||
64 | * Print indexed filenames to stdout. | 50 | * Print indexed filenames to stdout. |
65 | * | 51 | * |
66 | * @param cls closure | 52 | * @param cls closure |
@@ -71,6 +57,12 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
71 | static int | 57 | static int |
72 | print_indexed (void *cls, const char *filename, const GNUNET_HashCode * file_id) | 58 | print_indexed (void *cls, const char *filename, const GNUNET_HashCode * file_id) |
73 | { | 59 | { |
60 | if (NULL == filename) | ||
61 | { | ||
62 | GNUNET_FS_stop (fs); | ||
63 | fs = NULL; | ||
64 | return GNUNET_OK; | ||
65 | } | ||
74 | if (verbose) | 66 | if (verbose) |
75 | FPRINTF (stdout, "%s: %s\n", GNUNET_h2s (file_id), filename); | 67 | FPRINTF (stdout, "%s: %s\n", GNUNET_h2s (file_id), filename); |
76 | else | 68 | else |
@@ -100,7 +92,13 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
100 | ret = 1; | 92 | ret = 1; |
101 | return; | 93 | return; |
102 | } | 94 | } |
103 | GNUNET_FS_get_indexed_files (fs, &print_indexed, NULL, &do_shutdown, NULL); | 95 | if (NULL == GNUNET_FS_get_indexed_files (fs, &print_indexed, NULL)) |
96 | { | ||
97 | ret = 2; | ||
98 | GNUNET_FS_stop (fs); | ||
99 | fs = NULL; | ||
100 | return; | ||
101 | } | ||
104 | } | 102 | } |
105 | } | 103 | } |
106 | 104 | ||
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index 370f1062c..8f8d9147c 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c | |||
@@ -356,7 +356,7 @@ uri_ksk_continuation (void *cls, const struct GNUNET_FS_Uri *ksk_uri, | |||
356 | { | 356 | { |
357 | GNUNET_FS_publish_sks (ctx, ns, this_id, next_id, meta, uri, &bo, | 357 | GNUNET_FS_publish_sks (ctx, ns, this_id, next_id, meta, uri, &bo, |
358 | GNUNET_FS_PUBLISH_OPTION_NONE, | 358 | GNUNET_FS_PUBLISH_OPTION_NONE, |
359 | uri_sks_continuation, NULL); | 359 | &uri_sks_continuation, NULL); |
360 | GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_NO)); | 360 | GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_NO)); |
361 | return; | 361 | return; |
362 | } | 362 | } |