diff options
author | LRN <lrn1986@gmail.com> | 2013-02-19 04:04:35 +0000 |
---|---|---|
committer | LRN <lrn1986@gmail.com> | 2013-02-19 04:04:35 +0000 |
commit | 046e90172489ca6091346685bf444a037b1187ee (patch) | |
tree | b4649fab6e1cc543e26dcdd51d1aa8a79ec3d9d7 | |
parent | d924f127fd9633ce3e484d54a7efdcdee590dc34 (diff) | |
download | gnunet-046e90172489ca6091346685bf444a037b1187ee.tar.gz gnunet-046e90172489ca6091346685bf444a037b1187ee.zip |
Asynchronous namespace creation. With a test.
-rw-r--r-- | src/fs/fs_namespace.c | 149 | ||||
-rw-r--r-- | src/fs/test_fs_namespace.c | 149 | ||||
-rw-r--r-- | src/include/gnunet_fs_service.h | 39 |
3 files changed, 310 insertions, 27 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index f9cee5ff9..46121aa9c 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c | |||
@@ -38,6 +38,43 @@ | |||
38 | 38 | ||
39 | 39 | ||
40 | /** | 40 | /** |
41 | * Context for creating a namespace asynchronously. | ||
42 | */ | ||
43 | struct GNUNET_FS_NamespaceCreationContext | ||
44 | { | ||
45 | /** | ||
46 | * Context for asynchronous key creation. | ||
47 | */ | ||
48 | struct GNUNET_CRYPTO_RsaKeyGenerationContext *keycreator; | ||
49 | |||
50 | /** | ||
51 | * Name of the file to store key in / read key from. | ||
52 | */ | ||
53 | char *filename; | ||
54 | |||
55 | /** | ||
56 | * Name of the namespace. | ||
57 | */ | ||
58 | char *name; | ||
59 | |||
60 | /** | ||
61 | * Global fs handle | ||
62 | */ | ||
63 | struct GNUNET_FS_Handle *h; | ||
64 | |||
65 | /** | ||
66 | * Function to call when generation ends (successfully or not) | ||
67 | */ | ||
68 | GNUNET_FS_NamespaceCreationCallback cont; | ||
69 | |||
70 | /** | ||
71 | * Client value to pass to continuation function. | ||
72 | */ | ||
73 | void *cont_cls; | ||
74 | }; | ||
75 | |||
76 | |||
77 | /** | ||
41 | * Return the name of the directory in which we store | 78 | * Return the name of the directory in which we store |
42 | * our local namespaces (or rather, their public keys). | 79 | * our local namespaces (or rather, their public keys). |
43 | * | 80 | * |
@@ -268,6 +305,118 @@ GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name) | |||
268 | 305 | ||
269 | 306 | ||
270 | /** | 307 | /** |
308 | * Function called upon completion of 'GNUNET_CRYPTO_rsa_key_create_start'. | ||
309 | * | ||
310 | * @param cls closure | ||
311 | * @param pk NULL on error, otherwise the private key (which must be free'd by the callee) | ||
312 | * @param emsg NULL on success, otherwise an error message | ||
313 | */ | ||
314 | static void | ||
315 | ns_key_created (void *cls, struct GNUNET_CRYPTO_RsaPrivateKey *pk, | ||
316 | const char *emsg) | ||
317 | { | ||
318 | struct GNUNET_FS_NamespaceCreationContext *ncc = cls; | ||
319 | |||
320 | ncc->keycreator = NULL; | ||
321 | |||
322 | if (pk) | ||
323 | { | ||
324 | struct GNUNET_FS_Namespace *ret; | ||
325 | ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace)); | ||
326 | ret->rc = 1; | ||
327 | ret->key = pk; | ||
328 | ret->h = ncc->h; | ||
329 | ret->name = ncc->name; | ||
330 | ret->filename = ncc->filename; | ||
331 | ncc->cont (ncc->cont_cls, ret, NULL); | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | GNUNET_free (ncc->filename); | ||
336 | GNUNET_free (ncc->name); | ||
337 | ncc->cont (ncc->cont_cls, NULL, emsg); | ||
338 | } | ||
339 | GNUNET_free (ncc); | ||
340 | } | ||
341 | |||
342 | |||
343 | /** | ||
344 | * Create a namespace with the given name. | ||
345 | * If one already exists, the continuation will be called with a handle to | ||
346 | * the existing namespace. | ||
347 | * Otherwise creates a new namespace. | ||
348 | * | ||
349 | * @param h handle to the file sharing subsystem | ||
350 | * @param name name to use for the namespace | ||
351 | * @return namespace creation context, NULL on error (i.e. invalid filename) | ||
352 | */ | ||
353 | struct GNUNET_FS_NamespaceCreationContext * | ||
354 | GNUNET_FS_namespace_create_start (struct GNUNET_FS_Handle *h, const char *name, | ||
355 | GNUNET_FS_NamespaceCreationCallback cont, void *cont_cls) | ||
356 | { | ||
357 | char *dn; | ||
358 | char *fn; | ||
359 | struct GNUNET_FS_NamespaceCreationContext *ret; | ||
360 | |||
361 | dn = get_namespace_directory (h); | ||
362 | if (NULL == dn) | ||
363 | { | ||
364 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
365 | _("Can't determine where namespace directory is\n")); | ||
366 | return NULL; | ||
367 | } | ||
368 | GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name); | ||
369 | GNUNET_free (dn); | ||
370 | |||
371 | ret = GNUNET_malloc (sizeof (struct GNUNET_FS_NamespaceCreationContext)); | ||
372 | ret->filename = fn; | ||
373 | ret->h = h; | ||
374 | ret->name = GNUNET_strdup (name); | ||
375 | ret->cont = cont; | ||
376 | ret->cont_cls = cont_cls; | ||
377 | |||
378 | ret->keycreator = GNUNET_CRYPTO_rsa_key_create_start (fn, | ||
379 | ns_key_created, ret); | ||
380 | |||
381 | if (NULL == ret->keycreator) | ||
382 | { | ||
383 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
384 | _("Failed to start creating or reading private key for namespace `%s'\n"), | ||
385 | name); | ||
386 | GNUNET_free (fn); | ||
387 | GNUNET_free (ret->name); | ||
388 | GNUNET_free (ret); | ||
389 | return NULL; | ||
390 | } | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Abort namespace creation. | ||
397 | * | ||
398 | * @param ncc namespace creation context to abort | ||
399 | */ | ||
400 | void | ||
401 | GNUNET_FS_namespace_create_stop (struct GNUNET_FS_NamespaceCreationContext *ncc) | ||
402 | { | ||
403 | if (NULL != ncc->keycreator) | ||
404 | { | ||
405 | GNUNET_CRYPTO_rsa_key_create_stop (ncc->keycreator); | ||
406 | ncc->keycreator = NULL; | ||
407 | } | ||
408 | if (NULL != ncc->filename) | ||
409 | { | ||
410 | if (0 != UNLINK (ncc->filename)) | ||
411 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", ncc->filename); | ||
412 | GNUNET_free (ncc->filename); | ||
413 | } | ||
414 | GNUNET_free_non_null (ncc->name); | ||
415 | GNUNET_free (ncc); | ||
416 | } | ||
417 | |||
418 | |||
419 | /** | ||
271 | * Duplicate a namespace handle. | 420 | * Duplicate a namespace handle. |
272 | * | 421 | * |
273 | * @param ns namespace handle | 422 | * @param ns namespace handle |
diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c index e4ac4931e..61f304487 100644 --- a/src/fs/test_fs_namespace.c +++ b/src/fs/test_fs_namespace.c | |||
@@ -43,27 +43,64 @@ static struct GNUNET_FS_SearchContext *ksk_search; | |||
43 | 43 | ||
44 | static GNUNET_SCHEDULER_TaskIdentifier kill_task; | 44 | static GNUNET_SCHEDULER_TaskIdentifier kill_task; |
45 | 45 | ||
46 | static GNUNET_SCHEDULER_TaskIdentifier kill_ncc_task; | ||
47 | |||
48 | struct GNUNET_FS_NamespaceCreationContext *ncc; | ||
49 | |||
46 | static int update_started; | 50 | static int update_started; |
47 | 51 | ||
48 | static int err; | 52 | static int err; |
49 | 53 | ||
54 | static int phase; | ||
55 | |||
56 | const struct GNUNET_CONFIGURATION_Handle *config; | ||
57 | |||
58 | static void ns_created (void *cls, struct GNUNET_FS_Namespace *ns, const char *emsg); | ||
59 | |||
60 | static void do_ncc_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
61 | |||
50 | 62 | ||
51 | static void | 63 | static void |
52 | abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 64 | next_phase () |
53 | { | 65 | { |
54 | if (ksk_search != NULL) | 66 | switch (phase) |
55 | { | 67 | { |
56 | GNUNET_FS_search_stop (ksk_search); | 68 | case 0: |
57 | ksk_search = NULL; | 69 | phase += 1; |
58 | if (sks_search == NULL) | 70 | FPRINTF (stderr, "%s", "Testing asynchronous namespace creation\n"); |
71 | ncc = GNUNET_FS_namespace_create_start (fs, "testNamespace", ns_created, NULL); | ||
72 | if (NULL == ncc) | ||
59 | { | 73 | { |
60 | GNUNET_FS_stop (fs); | 74 | FPRINTF (stderr, "%s", "Failed to start asynchronous namespace creation\n"); |
61 | if (GNUNET_SCHEDULER_NO_TASK != kill_task) | 75 | err = 1; |
62 | GNUNET_SCHEDULER_cancel (kill_task); | 76 | next_phase (); |
77 | return; | ||
63 | } | 78 | } |
79 | kill_ncc_task = | ||
80 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_ncc_timeout, | ||
81 | NULL); | ||
82 | break; | ||
83 | case 1: | ||
84 | FPRINTF (stderr, "%s", "Shutting down FS\n"); | ||
85 | GNUNET_FS_stop (fs); | ||
86 | if (GNUNET_SCHEDULER_NO_TASK != kill_task) | ||
87 | GNUNET_SCHEDULER_cancel (kill_task); | ||
88 | kill_task = GNUNET_SCHEDULER_NO_TASK; | ||
64 | } | 89 | } |
65 | } | 90 | } |
66 | 91 | ||
92 | static void | ||
93 | abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
94 | { | ||
95 | if (NULL == ksk_search) | ||
96 | return; | ||
97 | FPRINTF (stderr, "%s", "Stopping KSK search\n"); | ||
98 | GNUNET_FS_search_stop (ksk_search); | ||
99 | ksk_search = NULL; | ||
100 | if (sks_search == NULL) | ||
101 | next_phase (); | ||
102 | } | ||
103 | |||
67 | 104 | ||
68 | static void | 105 | static void |
69 | abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 106 | abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
@@ -72,17 +109,14 @@ abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
72 | 109 | ||
73 | if (sks_search == NULL) | 110 | if (sks_search == NULL) |
74 | return; | 111 | return; |
112 | FPRINTF (stderr, "%s", "Stopping SKS search\n"); | ||
75 | GNUNET_FS_search_stop (sks_search); | 113 | GNUNET_FS_search_stop (sks_search); |
76 | sks_search = NULL; | 114 | sks_search = NULL; |
77 | ns = GNUNET_FS_namespace_create (fs, "testNamespace"); | 115 | ns = GNUNET_FS_namespace_create (fs, "testNamespace"); |
78 | GNUNET_assert (NULL != ns); | 116 | GNUNET_assert (NULL != ns); |
79 | GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES)); | 117 | GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES)); |
80 | if (ksk_search == NULL) | 118 | if (ksk_search == NULL) |
81 | { | 119 | next_phase (); |
82 | GNUNET_FS_stop (fs); | ||
83 | if (GNUNET_SCHEDULER_NO_TASK != kill_task) | ||
84 | GNUNET_SCHEDULER_cancel (kill_task); | ||
85 | } | ||
86 | } | 120 | } |
87 | 121 | ||
88 | 122 | ||
@@ -99,18 +133,25 @@ do_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
99 | static void * | 133 | static void * |
100 | progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) | 134 | progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) |
101 | { | 135 | { |
136 | char *got; | ||
102 | switch (event->status) | 137 | switch (event->status) |
103 | { | 138 | { |
104 | case GNUNET_FS_STATUS_SEARCH_RESULT: | 139 | case GNUNET_FS_STATUS_SEARCH_RESULT: |
140 | got = GNUNET_FS_uri_to_string (event->value.search.specifics.result.uri); | ||
141 | FPRINTF (stderr, "Got a search result `%s'\n", got); | ||
105 | if (sks_search == event->value.search.sc) | 142 | if (sks_search == event->value.search.sc) |
106 | { | 143 | { |
107 | if (!GNUNET_FS_uri_test_equal | 144 | if (!GNUNET_FS_uri_test_equal |
108 | (sks_expect_uri, event->value.search.specifics.result.uri)) | 145 | (sks_expect_uri, event->value.search.specifics.result.uri)) |
109 | { | 146 | { |
110 | FPRINTF (stderr, "%s", "Wrong result for sks search!\n"); | 147 | char *expected; |
148 | expected = GNUNET_FS_uri_to_string (sks_expect_uri); | ||
149 | FPRINTF (stderr, "Wrong result for sks search! Expected:\n%s\nGot:\n%s\n", expected, got); | ||
150 | GNUNET_free (expected); | ||
111 | err = 1; | 151 | err = 1; |
112 | } | 152 | } |
113 | /* give system 1ms to initiate update search! */ | 153 | /* give system 1ms to initiate update search! */ |
154 | FPRINTF (stderr, "scheduling `%s'\n", "abort_sks_search_task"); | ||
114 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, | 155 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, |
115 | &abort_sks_search_task, NULL); | 156 | &abort_sks_search_task, NULL); |
116 | } | 157 | } |
@@ -119,17 +160,22 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) | |||
119 | if (!GNUNET_FS_uri_test_equal | 160 | if (!GNUNET_FS_uri_test_equal |
120 | (ksk_expect_uri, event->value.search.specifics.result.uri)) | 161 | (ksk_expect_uri, event->value.search.specifics.result.uri)) |
121 | { | 162 | { |
122 | FPRINTF (stderr, "%s", "Wrong result for ksk search!\n"); | 163 | char *expected; |
164 | expected = GNUNET_FS_uri_to_string (ksk_expect_uri); | ||
165 | FPRINTF (stderr, "Wrong result for ksk search! Expected:\n%s\nGot:\n%s\n", expected, got); | ||
166 | GNUNET_free (expected); | ||
123 | err = 1; | 167 | err = 1; |
124 | } | 168 | } |
169 | FPRINTF (stderr, "scheduling `%s'\n", "abort_ksk_search_task"); | ||
125 | GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL, | 170 | GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL, |
126 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 171 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
127 | } | 172 | } |
128 | else | 173 | else |
129 | { | 174 | { |
130 | FPRINTF (stderr, "%s", "Unexpected search result received!\n"); | 175 | FPRINTF (stderr, "Unexpected search result `%s' received!\n", got); |
131 | GNUNET_break (0); | 176 | GNUNET_break (0); |
132 | } | 177 | } |
178 | GNUNET_free (got); | ||
133 | break; | 179 | break; |
134 | case GNUNET_FS_STATUS_SEARCH_ERROR: | 180 | case GNUNET_FS_STATUS_SEARCH_ERROR: |
135 | FPRINTF (stderr, "Error searching file: %s\n", | 181 | FPRINTF (stderr, "Error searching file: %s\n", |
@@ -144,6 +190,7 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) | |||
144 | GNUNET_break (0); | 190 | GNUNET_break (0); |
145 | break; | 191 | break; |
146 | case GNUNET_FS_STATUS_SEARCH_START: | 192 | case GNUNET_FS_STATUS_SEARCH_START: |
193 | FPRINTF (stderr, "Search %s started\n", event->value.search.pctx); | ||
147 | GNUNET_assert ((NULL == event->value.search.cctx) || | 194 | GNUNET_assert ((NULL == event->value.search.cctx) || |
148 | (0 == strcmp ("sks_search", event->value.search.cctx)) || | 195 | (0 == strcmp ("sks_search", event->value.search.cctx)) || |
149 | (0 == strcmp ("ksk_search", event->value.search.cctx))); | 196 | (0 == strcmp ("ksk_search", event->value.search.cctx))); |
@@ -155,8 +202,10 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) | |||
155 | GNUNET_assert (1 == event->value.search.anonymity); | 202 | GNUNET_assert (1 == event->value.search.anonymity); |
156 | break; | 203 | break; |
157 | case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED: | 204 | case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED: |
205 | FPRINTF (stderr, "%s", "Search result stopped\n"); | ||
158 | return NULL; | 206 | return NULL; |
159 | case GNUNET_FS_STATUS_SEARCH_STOPPED: | 207 | case GNUNET_FS_STATUS_SEARCH_STOPPED: |
208 | FPRINTF (stderr, "%s", "Search stopped\n"); | ||
160 | return NULL; | 209 | return NULL; |
161 | default: | 210 | default: |
162 | FPRINTF (stderr, "Unexpected event: %d\n", event->status); | 211 | FPRINTF (stderr, "Unexpected event: %d\n", event->status); |
@@ -176,11 +225,12 @@ publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg) | |||
176 | 225 | ||
177 | if (NULL != emsg) | 226 | if (NULL != emsg) |
178 | { | 227 | { |
179 | FPRINTF (stderr, "Error publishing: %s\n", emsg); | 228 | FPRINTF (stderr, "Error publishing ksk: %s\n", emsg); |
180 | err = 1; | 229 | err = 1; |
181 | GNUNET_FS_stop (fs); | 230 | GNUNET_FS_stop (fs); |
182 | return; | 231 | return; |
183 | } | 232 | } |
233 | FPRINTF (stderr, "%s", "Published ksk\n"); | ||
184 | GNUNET_CRYPTO_hash_to_enc (&nsid, &enc); | 234 | GNUNET_CRYPTO_hash_to_enc (&nsid, &enc); |
185 | GNUNET_snprintf (sbuf, sizeof (sbuf), "gnunet://fs/sks/%s/this", &enc); | 235 | GNUNET_snprintf (sbuf, sizeof (sbuf), "gnunet://fs/sks/%s/this", &enc); |
186 | sks_uri = GNUNET_FS_uri_parse (sbuf, &msg); | 236 | sks_uri = GNUNET_FS_uri_parse (sbuf, &msg); |
@@ -192,6 +242,7 @@ publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg) | |||
192 | GNUNET_free_non_null (msg); | 242 | GNUNET_free_non_null (msg); |
193 | return; | 243 | return; |
194 | } | 244 | } |
245 | FPRINTF (stderr, "%s", "Starting searches\n"); | ||
195 | ksk_search = | 246 | ksk_search = |
196 | GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE, | 247 | GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE, |
197 | "ksk_search"); | 248 | "ksk_search"); |
@@ -212,11 +263,12 @@ sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) | |||
212 | 263 | ||
213 | if (NULL == uri) | 264 | if (NULL == uri) |
214 | { | 265 | { |
215 | fprintf (stderr, "Error publishing: %s\n", emsg); | 266 | fprintf (stderr, "Error publishing sks: %s\n", emsg); |
216 | err = 1; | 267 | err = 1; |
217 | GNUNET_FS_stop (fs); | 268 | GNUNET_FS_stop (fs); |
218 | return; | 269 | return; |
219 | } | 270 | } |
271 | FPRINTF (stderr, "%s", "Published sks\n"); | ||
220 | meta = GNUNET_CONTAINER_meta_data_create (); | 272 | meta = GNUNET_CONTAINER_meta_data_create (); |
221 | msg = NULL; | 273 | msg = NULL; |
222 | ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg); | 274 | ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg); |
@@ -243,11 +295,12 @@ adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) | |||
243 | 295 | ||
244 | if (NULL != emsg) | 296 | if (NULL != emsg) |
245 | { | 297 | { |
246 | FPRINTF (stderr, "Error publishing: %s\n", emsg); | 298 | FPRINTF (stderr, "Error advertising: %s\n", emsg); |
247 | err = 1; | 299 | err = 1; |
248 | GNUNET_FS_stop (fs); | 300 | GNUNET_FS_stop (fs); |
249 | return; | 301 | return; |
250 | } | 302 | } |
303 | FPRINTF (stderr, "%s", "Created an advertising\n"); | ||
251 | ns = GNUNET_FS_namespace_create (fs, "testNamespace"); | 304 | ns = GNUNET_FS_namespace_create (fs, "testNamespace"); |
252 | GNUNET_assert (NULL != ns); | 305 | GNUNET_assert (NULL != ns); |
253 | meta = GNUNET_CONTAINER_meta_data_create (); | 306 | meta = GNUNET_CONTAINER_meta_data_create (); |
@@ -270,24 +323,22 @@ ns_iterator (void *cls, const char *name, const struct GNUNET_HashCode * id) | |||
270 | { | 323 | { |
271 | int *ok = cls; | 324 | int *ok = cls; |
272 | 325 | ||
326 | FPRINTF (stderr, "Namespace in the list: %s\n", name); | ||
273 | if (0 != strcmp (name, "testNamespace")) | 327 | if (0 != strcmp (name, "testNamespace")) |
274 | return; | 328 | return; |
275 | *ok = GNUNET_YES; | 329 | *ok = GNUNET_YES; |
276 | nsid = *id; | 330 | nsid = *id; |
277 | } | 331 | } |
278 | 332 | ||
279 | |||
280 | static void | 333 | static void |
281 | testNamespace () | 334 | testCreatedNamespace (struct GNUNET_FS_Namespace *ns) |
282 | { | 335 | { |
283 | struct GNUNET_FS_Namespace *ns; | ||
284 | struct GNUNET_FS_BlockOptions bo; | 336 | struct GNUNET_FS_BlockOptions bo; |
285 | struct GNUNET_CONTAINER_MetaData *meta; | 337 | struct GNUNET_CONTAINER_MetaData *meta; |
286 | struct GNUNET_FS_Uri *ksk_uri; | 338 | struct GNUNET_FS_Uri *ksk_uri; |
287 | int ok; | 339 | int ok; |
288 | 340 | ||
289 | ns = GNUNET_FS_namespace_create (fs, "testNamespace"); | 341 | FPRINTF (stderr, "%s", "Listing namespaces\n"); |
290 | GNUNET_assert (NULL != ns); | ||
291 | ok = GNUNET_NO; | 342 | ok = GNUNET_NO; |
292 | GNUNET_FS_namespace_list (fs, &ns_iterator, &ok); | 343 | GNUNET_FS_namespace_list (fs, &ns_iterator, &ok); |
293 | if (GNUNET_NO == ok) | 344 | if (GNUNET_NO == ok) |
@@ -298,6 +349,7 @@ testNamespace () | |||
298 | err = 1; | 349 | err = 1; |
299 | return; | 350 | return; |
300 | } | 351 | } |
352 | FPRINTF (stderr, "%s", "Creating an advertising\n"); | ||
301 | meta = GNUNET_CONTAINER_meta_data_create (); | 353 | meta = GNUNET_CONTAINER_meta_data_create (); |
302 | ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL); | 354 | ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL); |
303 | bo.content_priority = 1; | 355 | bo.content_priority = 1; |
@@ -307,22 +359,65 @@ testNamespace () | |||
307 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); | 359 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); |
308 | GNUNET_FS_namespace_advertise (fs, ksk_uri, ns, meta, &bo, "root", &adv_cont, | 360 | GNUNET_FS_namespace_advertise (fs, ksk_uri, ns, meta, &bo, "root", &adv_cont, |
309 | NULL); | 361 | NULL); |
310 | kill_task = | ||
311 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout, | ||
312 | NULL); | ||
313 | GNUNET_FS_uri_destroy (ksk_uri); | 362 | GNUNET_FS_uri_destroy (ksk_uri); |
314 | GNUNET_FS_namespace_delete (ns, GNUNET_NO); | 363 | GNUNET_FS_namespace_delete (ns, GNUNET_NO); |
315 | GNUNET_CONTAINER_meta_data_destroy (meta); | 364 | GNUNET_CONTAINER_meta_data_destroy (meta); |
316 | } | 365 | } |
317 | 366 | ||
367 | static void | ||
368 | do_ncc_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
369 | { | ||
370 | FPRINTF (stderr, "%s", "Asynchronous NS creation timed out\n"); | ||
371 | kill_ncc_task = GNUNET_SCHEDULER_NO_TASK; | ||
372 | if (NULL == ncc) | ||
373 | return; | ||
374 | GNUNET_FS_namespace_create_stop (ncc); | ||
375 | ncc = NULL; | ||
376 | err = 1; | ||
377 | } | ||
378 | |||
379 | static void | ||
380 | ns_created (void *cls, struct GNUNET_FS_Namespace *ns, const char *emsg) | ||
381 | { | ||
382 | if (GNUNET_SCHEDULER_NO_TASK != kill_ncc_task) | ||
383 | GNUNET_SCHEDULER_cancel (kill_ncc_task); | ||
384 | kill_ncc_task = GNUNET_SCHEDULER_NO_TASK; | ||
385 | if (NULL == ns) | ||
386 | { | ||
387 | FPRINTF (stderr, "Asynchronous NS creation failed: %s\n", emsg); | ||
388 | err = 1; | ||
389 | return; | ||
390 | } | ||
391 | |||
392 | FPRINTF (stderr, "%s", "Namespace created asynchronously\n"); | ||
393 | testCreatedNamespace (ns); | ||
394 | } | ||
395 | |||
396 | static void | ||
397 | testNamespace () | ||
398 | { | ||
399 | struct GNUNET_FS_Namespace *ns; | ||
400 | |||
401 | FPRINTF (stderr, "%s", "Testing synchronous namespace creation\n"); | ||
402 | ns = GNUNET_FS_namespace_create (fs, "testNamespace"); | ||
403 | GNUNET_assert (NULL != ns); | ||
404 | testCreatedNamespace (ns); | ||
405 | |||
406 | kill_task = | ||
407 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout, | ||
408 | NULL); | ||
409 | } | ||
410 | |||
318 | 411 | ||
319 | static void | 412 | static void |
320 | run (void *cls, | 413 | run (void *cls, |
321 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 414 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
322 | struct GNUNET_TESTING_Peer *peer) | 415 | struct GNUNET_TESTING_Peer *peer) |
323 | { | 416 | { |
417 | config = cfg; | ||
324 | fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL, | 418 | fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL, |
325 | GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); | 419 | GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); |
420 | phase = 0; | ||
326 | testNamespace (); | 421 | testNamespace (); |
327 | } | 422 | } |
328 | 423 | ||
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index a80662867..d6b26d927 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h | |||
@@ -2240,6 +2240,45 @@ GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name); | |||
2240 | 2240 | ||
2241 | 2241 | ||
2242 | /** | 2242 | /** |
2243 | * Context for creating a namespace asynchronously. | ||
2244 | */ | ||
2245 | struct GNUNET_FS_NamespaceCreationContext; | ||
2246 | |||
2247 | /** | ||
2248 | * Function called upon completion of 'GNUNET_FS_namespace_create_start'. | ||
2249 | * | ||
2250 | * @param cls closure | ||
2251 | * @param ns NULL on error, otherwise the namespace (which must be free'd by the callee) | ||
2252 | * @param emsg NULL on success, otherwise an error message | ||
2253 | */ | ||
2254 | typedef void (*GNUNET_FS_NamespaceCreationCallback)(void *cls, | ||
2255 | struct GNUNET_FS_Namespace *ns, const char *emsg); | ||
2256 | |||
2257 | |||
2258 | /** | ||
2259 | * Create a namespace with the given name; if one already | ||
2260 | * exists, return a handle to the existing namespace immediately. | ||
2261 | * Otherwise create a namespace asynchronously. | ||
2262 | * | ||
2263 | * @param h handle to the file sharing subsystem | ||
2264 | * @param name name to use for the namespace | ||
2265 | * @return namespace creation context, NULL on error (i.e. invalid filename) | ||
2266 | */ | ||
2267 | struct GNUNET_FS_NamespaceCreationContext * | ||
2268 | GNUNET_FS_namespace_create_start (struct GNUNET_FS_Handle *h, const char *name, | ||
2269 | GNUNET_FS_NamespaceCreationCallback cont, void *cont_cls); | ||
2270 | |||
2271 | |||
2272 | /** | ||
2273 | * Abort namespace creation. | ||
2274 | * | ||
2275 | * @param ncc namespace creation context to abort | ||
2276 | */ | ||
2277 | void | ||
2278 | GNUNET_FS_namespace_create_stop (struct GNUNET_FS_NamespaceCreationContext *ncc); | ||
2279 | |||
2280 | |||
2281 | /** | ||
2243 | * Duplicate a namespace handle. | 2282 | * Duplicate a namespace handle. |
2244 | * | 2283 | * |
2245 | * @param ns namespace handle | 2284 | * @param ns namespace handle |