aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_namespace_advertise.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fs_namespace_advertise.c')
-rw-r--r--src/fs/fs_namespace_advertise.c363
1 files changed, 0 insertions, 363 deletions
diff --git a/src/fs/fs_namespace_advertise.c b/src/fs/fs_namespace_advertise.c
deleted file mode 100644
index 554f61657..000000000
--- a/src/fs/fs_namespace_advertise.c
+++ /dev/null
@@ -1,363 +0,0 @@
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 */
43struct 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 */
110static void
111do_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 */
128static void
129advertisement_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 struct GNUNET_HashCode key;
136 struct 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 * Create an SKS uri that points to the root entry of the namespace,
204 * then insert that SKS uri into metadata.
205 *
206 * @param ns handle for the namespace that should be advertised
207 * @param meta meta-data into which namespace advertisement should be inserted
208 * @param rootEntry name of the root of the namespace (use NULL to use default)
209 * @return GNUNET_OK on success, GNUNET_SYSERR on error
210 */
211int
212GNUNET_FS_namespace_insert_advertisement_into_metadata (
213 struct GNUNET_FS_Namespace *ns, struct GNUNET_CONTAINER_MetaData *meta,
214 const char *rootEntry)
215{
216 struct GNUNET_FS_Uri *sks_uri;
217 char *emsg;
218 char *sks_uri_string;
219 int md_insert;
220
221 if (NULL == rootEntry)
222 rootEntry = "/";
223
224 emsg = NULL;
225 sks_uri = GNUNET_FS_uri_sks_create (ns, rootEntry, &emsg);
226 GNUNET_free_non_null (emsg);
227 if (NULL == sks_uri)
228 return GNUNET_SYSERR;
229
230 sks_uri_string = GNUNET_FS_uri_to_string (sks_uri);
231 GNUNET_FS_uri_destroy (sks_uri);
232 if (NULL == sks_uri_string)
233 return GNUNET_SYSERR;
234
235 md_insert = GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>",
236 EXTRACTOR_METATYPE_URI, EXTRACTOR_METAFORMAT_UTF8,
237 "text/plain", sks_uri_string, strlen (sks_uri_string) + 1);
238 GNUNET_free (sks_uri_string);
239 return md_insert;
240}
241
242/**
243 * Publish an advertismement for a namespace.
244 *
245 * @param h handle to the file sharing subsystem
246 * @param ksk_uri keywords to use for advertisment
247 * @param ns handle for the namespace that should be advertised
248 * @param meta meta-data for the namespace advertisement
249 * @param bo block options
250 * @param rootEntry name of the root of the namespace
251 * @param cont continuation
252 * @param cont_cls closure for cont
253 * @return NULL on error ('cont' is still called)
254 */
255struct GNUNET_FS_AdvertisementContext *
256GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h,
257 struct GNUNET_FS_Uri *ksk_uri,
258 struct GNUNET_FS_Namespace *ns,
259 const struct GNUNET_CONTAINER_MetaData *meta,
260 const struct GNUNET_FS_BlockOptions *bo,
261 const char *rootEntry,
262 GNUNET_FS_PublishContinuation cont,
263 void *cont_cls)
264{
265 size_t reslen;
266 size_t size;
267 ssize_t mdsize;
268 struct NBlock *nb;
269 char *mdst;
270 struct GNUNET_DATASTORE_Handle *dsh;
271 struct GNUNET_FS_AdvertisementContext *ctx;
272 char *pt;
273
274 /* create advertisements */
275 mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
276 if (-1 == mdsize)
277 {
278 cont (cont_cls, NULL, _("Failed to serialize meta data"));
279 return NULL;
280 }
281 reslen = strlen (rootEntry) + 1;
282 size = mdsize + sizeof (struct NBlock) + reslen;
283 if (size > MAX_NBLOCK_SIZE)
284 {
285 size = MAX_NBLOCK_SIZE;
286 mdsize = size - sizeof (struct NBlock) - reslen;
287 }
288
289 pt = GNUNET_malloc (mdsize + reslen);
290 memcpy (pt, rootEntry, reslen);
291 mdst = &pt[reslen];
292 mdsize =
293 GNUNET_CONTAINER_meta_data_serialize (meta, &mdst, mdsize,
294 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
295 if (-1 == mdsize)
296 {
297 GNUNET_break (0);
298 GNUNET_free (pt);
299 cont (cont_cls, NULL, _("Failed to serialize meta data"));
300 return NULL;
301 }
302 size = mdsize + sizeof (struct NBlock) + reslen;
303 nb = GNUNET_malloc (size);
304 GNUNET_CRYPTO_rsa_key_get_public (ns->key, &nb->subspace);
305 nb->ns_purpose.size =
306 htonl (mdsize + reslen +
307 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
308 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
309 nb->ns_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK);
310 nb->ksk_purpose.size =
311 htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature));
312 nb->ksk_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG);
313 dsh = GNUNET_DATASTORE_connect (h->cfg);
314 if (NULL == dsh)
315 {
316 GNUNET_free (nb);
317 GNUNET_free (pt);
318 cont (cont_cls, NULL, _("Failed to connect to datastore service"));
319 return NULL;
320 }
321 ctx = GNUNET_malloc (sizeof (struct GNUNET_FS_AdvertisementContext));
322 ctx->cont = cont;
323 ctx->cont_cls = cont_cls;
324 ctx->dsh = dsh;
325 ctx->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
326 ctx->nb = nb;
327 ctx->pt = pt;
328 ctx->pt_size = mdsize + reslen;
329 ctx->ns = ns;
330 ctx->ns->rc++;
331 ctx->bo = *bo;
332 advertisement_cont (ctx, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL);
333 return ctx;
334}
335
336
337/**
338 * Abort the namespace advertisement operation.
339 *
340 * @param ac context of the operation to abort.
341 */
342void
343GNUNET_FS_namespace_advertise_cancel (struct GNUNET_FS_AdvertisementContext *ac)
344{
345 if (NULL != ac->dqe)
346 {
347 GNUNET_DATASTORE_cancel (ac->dqe);
348 ac->dqe = NULL;
349 }
350 if (NULL != ac->dsh)
351 {
352 GNUNET_DATASTORE_disconnect (ac->dsh, GNUNET_NO);
353 ac->dsh = NULL;
354 }
355 GNUNET_FS_uri_destroy (ac->ksk_uri);
356 GNUNET_free (ac->pt);
357 GNUNET_free (ac->nb);
358 GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO);
359 GNUNET_free (ac);
360}
361
362
363/* end of fs_namespace_advertise.c */