aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-03-24 09:58:58 +0000
committerChristian Grothoff <christian@grothoff.org>2010-03-24 09:58:58 +0000
commit3aea10e56e9f4b4971dd2626bd4f69ea796787e2 (patch)
tree6d263f237a226e10439005bdd32ba6160d8e9a19
parenta313004af348121545a63abedbe6456944c5fe16 (diff)
downloadgnunet-3aea10e56e9f4b4971dd2626bd4f69ea796787e2.tar.gz
gnunet-3aea10e56e9f4b4971dd2626bd4f69ea796787e2.zip
stuff
-rw-r--r--TODO34
-rw-r--r--contrib/defaults.conf1
-rw-r--r--src/fs/fs.h49
-rw-r--r--src/fs/fs_namespace.c890
-rw-r--r--src/fs/fs_publish.c134
-rw-r--r--src/fs/gnunet-service-fs.c10
-rw-r--r--src/hello/hello.c2
-rw-r--r--src/include/gnunet_common.h2
-rw-r--r--src/include/gnunet_datastore_service.h4
-rw-r--r--src/include/gnunet_fs_service.h22
-rw-r--r--src/include/gnunet_hello_lib.h4
-rw-r--r--src/include/gnunet_signatures.h7
-rw-r--r--src/topology/gnunet-daemon-topology.c1
13 files changed, 482 insertions, 678 deletions
diff --git a/TODO b/TODO
index 9cd5e7739..6b7dee43e 100644
--- a/TODO
+++ b/TODO
@@ -23,24 +23,15 @@ away), in order in which they will likely be done:
23 sessions even if no connections exist for a while! (likely related...) 23 sessions even if no connections exist for a while! (likely related...)
24 - transport reports bw quota violations on big-endian systems (core or 24 - transport reports bw quota violations on big-endian systems (core or
25 transport issue?) 25 transport issue?)
26* HELLO:
27 - need function to test "equivalency" of HELLOs; use in topology!
28* FS: 26* FS:
29 - GAP improvements:
30 + active reply route caching design & implementation of service,
31 gap extension!
32 - gnunet-publish cannot be aborted using CTRL-C 27 - gnunet-publish cannot be aborted using CTRL-C
33 - on some systems, keyword search does not find locally published content 28 - on some systems, keyword search does not find locally published content
34 (need testcase of command-line tools!) 29 (need testcase of command-line tools!)
35 - 2-peer download is still too slow (why?) 30 - 2-peer download is still too slow (why?)
36 - advanced FS API parts 31 - advanced FS API parts
37 + namespaces: fundamental namespace API 32 + search: SBlocks, NBlocks, probes, notify FS-service of known results
38 + search: SBlocks, KSBlocks, probes, notify FS-service of known results
39 + collection
40 + location URIs (publish, search, download) 33 + location URIs (publish, search, download)
41 + indexing: index-failure-cleanup 34 + indexing: index-failure-cleanup
42 + download: management/bounding of parallel downloads (for recursive dl.)
43 + datastore reservation (publishing)
44 + gnunet-publish (URI args) 35 + gnunet-publish (URI args)
45 + gnunet-download (directory) 36 + gnunet-download (directory)
46 + gnunet-search (options, incl. namespace search) 37 + gnunet-search (options, incl. namespace search)
@@ -52,14 +43,8 @@ away), in order in which they will likely be done:
52 + getopt API 43 + getopt API
53 + insert: sblocks, loc uris 44 + insert: sblocks, loc uris
54 + download: loc uris 45 + download: loc uris
55 + search: sblocks, skblocks, loc uris 46 + search: sblocks, nblocks, loc uris
56 + namespaces 47 + namespaces
57 + collection
58 - implement FS performance tests
59 + insert
60 + download
61 + search
62 + unindex
63 - [./fs/gnunet-service-fs.c:208]: (style) struct or union member 'LocalGetContext::results_bf_size' is never used 48 - [./fs/gnunet-service-fs.c:208]: (style) struct or union member 'LocalGetContext::results_bf_size' is never used
64 - [./fs/gnunet-service-fs.c:501]: (style) struct or union member 'PendingRequest::used_pids_size' is never used 49 - [./fs/gnunet-service-fs.c:501]: (style) struct or union member 'PendingRequest::used_pids_size' is never used
65 - [./fs/gnunet-service-fs.c:654]: (style) struct or union member 'ConnectedPeer::last_client_replies' is never used 50 - [./fs/gnunet-service-fs.c:654]: (style) struct or union member 'ConnectedPeer::last_client_replies' is never used
@@ -100,12 +85,16 @@ away), in order in which they will likely be done:
100 [On W32, we need to select after calling socket before 85 [On W32, we need to select after calling socket before
101 doing connect etc.] 86 doing connect etc.]
102* FS: 87* FS:
88 - datastore reservation (publishing)
103 - persistence support (publish, unindex, search, download) 89 - persistence support (publish, unindex, search, download)
90 - download: management/bounding of parallel downloads (for recursive dl.)
104 - non-anonymous FS service (needs DHT) 91 - non-anonymous FS service (needs DHT)
105 + basic DHT integration 92 + basic DHT integration
106 + CS-DHT-functions (DHT-put of LOC) 93 + CS-DHT-functions (DHT-put of LOC)
107 + P2P-functions (DHT-get) 94 + P2P-functions (DHT-get)
108 - active migration support (in fs or in datastore?) 95 - active migration support (in fs or in datastore or new daemon?)
96 - GAP improvements:
97 + active reply route caching design & implementation of service; gap extension!
109* TOPOLOGY: 98* TOPOLOGY:
110 - needs more testing (especially F2F topology) 99 - needs more testing (especially F2F topology)
111 - needs to re-try connecting after disconnect (currently, it 100 - needs to re-try connecting after disconnect (currently, it
@@ -134,6 +123,8 @@ away), in order in which they will likely be done:
134 more balanced load) 123 more balanced load)
135 - check if new HELLO learned is different from old HELLO 124 - check if new HELLO learned is different from old HELLO
136 before resetting entire state! 125 before resetting entire state!
126* HELLO:
127 - need function to test "equivalency" of HELLOs (or integrate with "merge"?); use in PEERINFO
137 128
1380.9.0pre2: 1290.9.0pre2:
139* Module features to implement: 130* Module features to implement:
@@ -160,6 +151,13 @@ away), in order in which they will likely be done:
160 - better crash management (attach debugging support, capture and analyze 151 - better crash management (attach debugging support, capture and analyze
161 debug output, detect random vs. deterministic crashes) 152 debug output, detect random vs. deterministic crashes)
162 - shutdown sequence? 153 - shutdown sequence?
154* FS:
155 - collection API & tests
156 - implement FS performance tests
157 + insert
158 + download
159 + search
160 + unindex
163 161
164 162
1650.9.0pre3: 1630.9.0pre3:
diff --git a/contrib/defaults.conf b/contrib/defaults.conf
index f7750a0a8..1259a82d0 100644
--- a/contrib/defaults.conf
+++ b/contrib/defaults.conf
@@ -188,6 +188,7 @@ FILENAME = $SERVICEHOME/datastore/sqlite.db
188 188
189[fs] 189[fs]
190INDEXDB = $SERVICEHOME/idxinfo.lst 190INDEXDB = $SERVICEHOME/idxinfo.lst
191IDENTITY_DIR = $SERVICEHOME/identities/
191PORT = 2094 192PORT = 2094
192HOSTNAME = localhost 193HOSTNAME = localhost
193HOME = $SERVICEHOME 194HOME = $SERVICEHOME
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 67bb6f4dd..0d4ed268a 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -35,6 +35,20 @@
35 */ 35 */
36#define DBLOCK_SIZE (32*1024) 36#define DBLOCK_SIZE (32*1024)
37 37
38/**
39 * Maximum legal size for a kblock.
40 */
41#define MAX_KBLOCK_SIZE (60 * 1024)
42
43/**
44 * Maximum legal size for an sblock.
45 */
46#define MAX_SBLOCK_SIZE (60 * 1024)
47
48/**
49 * Maximum legal size for an nblock.
50 */
51#define MAX_NBLOCK_SIZE (60 * 1024)
38 52
39/** 53/**
40 * Pick a multiple of 2 here to achive 8-byte alignment! 54 * Pick a multiple of 2 here to achive 8-byte alignment!
@@ -1037,6 +1051,11 @@ struct GNUNET_FS_Namespace
1037 struct GNUNET_CRYPTO_RsaPrivateKey *key; 1051 struct GNUNET_CRYPTO_RsaPrivateKey *key;
1038 1052
1039 /** 1053 /**
1054 * Name of the file with the private key.
1055 */
1056 char *filename;
1057
1058 /**
1040 * Reference counter. 1059 * Reference counter.
1041 */ 1060 */
1042 unsigned int rc; 1061 unsigned int rc;
@@ -1124,7 +1143,35 @@ struct SBlock
1124 1143
1125 /* 0-terminated update-identifier here */ 1144 /* 0-terminated update-identifier here */
1126 1145
1127 /* 0-terminated URI here */ 1146 /* 0-terminated URI here (except for NBlocks) */
1147
1148 /* variable-size Meta-Data follows here */
1149
1150};
1151
1152
1153/**
1154 * @brief namespace advertisement block (advertising root of a namespace)
1155 */
1156struct NBlock
1157{
1158
1159 /**
1160 * GNUNET_RSA_Signature using RSA-key of the namespace
1161 */
1162 struct GNUNET_CRYPTO_RsaSignature signature;
1163
1164 /**
1165 * What is being signed and why?
1166 */
1167 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
1168
1169 /**
1170 * Public key of the namespace.
1171 */
1172 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded subspace;
1173
1174 /* 0-terminated root identifier here */
1128 1175
1129 /* variable-size Meta-Data follows here */ 1176 /* variable-size Meta-Data follows here */
1130 1177
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index a72a64a49..c040bad76 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -24,7 +24,90 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_constants.h"
28#include "gnunet_signatures.h"
29#include "gnunet_util_lib.h"
27#include "gnunet_fs_service.h" 30#include "gnunet_fs_service.h"
31#include "fs.h"
32
33/**
34 * Return the name of the directory in which we store
35 * our local namespaces (or rather, their public keys).
36 *
37 * @param h global fs handle
38 * @return NULL on error, otherwise the name of the directory
39 */
40static char *
41get_namespace_directory (struct GNUNET_FS_Handle *h)
42{
43 char *dn;
44
45 if (GNUNET_OK !=
46 GNUNET_CONFIGURATION_get_value_filename (h->cfg,
47 "FS",
48 "IDENTITY_DIR",
49 &dn))
50 {
51 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
52 _("Configuration fails to specify `%s' in section `%s'\n"),
53 "IDENTITY_DIR",
54 "fs");
55 return NULL;
56 }
57 return dn;
58}
59
60
61/**
62 * Context for advertising a namespace.
63 */
64struct AdvertisementContext
65{
66 /**
67 * Function to call with the result.
68 */
69 GNUNET_FS_PublishContinuation cont;
70
71 /**
72 * Closure for cont.
73 */
74 void *cont_cls;
75
76 /**
77 * Datastore handle.
78 */
79 struct GNUNET_DATASTORE_Handle *dsh;
80
81 /**
82 * URI that was created.
83 */
84 struct GNUNET_FS_Uri *uri;
85};
86
87
88/**
89 * Continuation called to notify client about result of the
90 * operation.
91 *
92 * @param cls closure (our struct AdvertismentContext)
93 * @param success GNUNET_SYSERR on failure
94 * @param msg NULL on success, otherwise an error message
95 */
96static void
97advertisement_cont (void *cls,
98 int success,
99 const char *msg)
100{
101 struct AdvertisementContext *ac = cls;
102
103 if (GNUNET_OK != success)
104 ac->cont (ac->cont_cls, NULL, msg);
105 else
106 ac->cont (ac->cont_cls, ac->uri, NULL);
107 GNUNET_DATASTORE_disconnect (ac->dsh, GNUNET_NO);
108 GNUNET_FS_uri_destroy (ac->uri);
109 GNUNET_free (ac);
110}
28 111
29 112
30/** 113/**
@@ -36,25 +119,96 @@
36 * @param anonymity for the namespace advertismement 119 * @param anonymity for the namespace advertismement
37 * @param priority for the namespace advertisement 120 * @param priority for the namespace advertisement
38 * @param expiration for the namespace advertisement 121 * @param expiration for the namespace advertisement
39 * @param advertisementURI the keyword (!) URI to advertise the 122 * @param rootEntry name of the root of the namespace
40 * namespace under (we will create a GNUNET_EC_KNBlock) 123 * @param cont continuation
41 * @param rootEntry name of the root entry in the namespace (for 124 * @param cont_cls closure for cont
42 * the namespace advertisement)
43 *
44 * @return uri of the advertisement
45 */ 125 */
46struct GNUNET_FS_Uri * 126void
47GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, 127GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h,
48 struct GNUNET_FS_Namespace *namespace, 128 struct GNUNET_FS_Namespace *namespace,
49 const struct GNUNET_CONTAINER_MetaData *meta, 129 const struct GNUNET_CONTAINER_MetaData *meta,
50 uint32_t anonymity, 130 uint32_t anonymity,
51 uint32_t priority, 131 uint32_t priority,
52 struct GNUNET_TIME_Absolute expiration, 132 struct GNUNET_TIME_Absolute expiration,
53 const struct GNUNET_FS_Uri *advertisementURI, 133 const char *rootEntry,
54 const char *rootEntry) 134 GNUNET_FS_PublishContinuation cont,
135 void *cont_cls)
55{ 136{
56 GNUNET_break (0); 137 size_t reslen;
57 return NULL; 138 size_t size;
139 ssize_t mdsize;
140 struct NBlock *nb;
141 char *rtgt;
142 char *mdst;
143 struct GNUNET_DATASTORE_Handle *dsh;
144 struct AdvertisementContext *ctx;
145
146 /* create advertisements */
147 mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
148 if (-1 == mdsize)
149 {
150 cont (cont_cls, NULL, _("Failed to serialize meta data"));
151 return;
152 }
153 reslen = strlen (rootEntry) + 1;
154 size = mdsize + sizeof (struct NBlock) + reslen;
155 if (size > MAX_NBLOCK_SIZE)
156 {
157 size = MAX_NBLOCK_SIZE;
158 mdsize = size - sizeof (struct NBlock) - reslen;
159 }
160 nb = GNUNET_malloc (size);
161 GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &nb->subspace);
162 rtgt = (char *) &nb[1];
163 memcpy (rtgt, rootEntry, reslen);
164 mdst = &rtgt[reslen];
165 mdsize = GNUNET_CONTAINER_meta_data_serialize (meta,
166 &mdst,
167 mdsize,
168 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
169 if (mdsize == -1)
170 {
171 GNUNET_break (0);
172 GNUNET_free (nb);
173 cont (cont_cls, NULL, _("Failed to serialize meta data"));
174 return;
175 }
176 size = mdsize + sizeof (struct NBlock) + reslen;
177 nb->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature));
178 nb->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK);
179 GNUNET_break (GNUNET_OK ==
180 GNUNET_CRYPTO_rsa_sign (namespace->key,
181 &nb->purpose,
182 &nb->signature));
183 dsh = GNUNET_DATASTORE_connect (h->cfg, h->sched);
184 if (NULL == dsh)
185 {
186 GNUNET_free (nb);
187 cont (cont_cls, NULL, _("Failed to connect to datastore service"));
188 return;
189 }
190 ctx = GNUNET_malloc (sizeof (struct AdvertisementContext));
191 ctx->cont = cont;
192 ctx->cont_cls = cont_cls;
193 ctx->dsh = dsh;
194 ctx->uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
195 ctx->uri->type = sks;
196 ctx->uri->data.sks.identifier = GNUNET_strdup ("");
197 GNUNET_CRYPTO_hash (&nb->subspace,
198 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
199 &ctx->uri->data.sks.namespace);
200 GNUNET_DATASTORE_put (dsh,
201 0,
202 &ctx->uri->data.sks.namespace,
203 size,
204 nb,
205 GNUNET_DATASTORE_BLOCKTYPE_NBLOCK,
206 priority,
207 anonymity,
208 expiration,
209 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
210 &advertisement_cont,
211 ctx);
58} 212}
59 213
60 214
@@ -70,8 +224,30 @@ struct GNUNET_FS_Namespace *
70GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, 224GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h,
71 const char *name) 225 const char *name)
72{ 226{
73 GNUNET_break (0); 227 char *dn;
74 return NULL; 228 char *fn;
229 struct GNUNET_FS_Namespace *ret;
230
231 dn = get_namespace_directory (h);
232 GNUNET_asprintf (&fn,
233 "%s%s%s",
234 dn,
235 DIR_SEPARATOR_STR,
236 name);
237 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
238 ret->rc = 1;
239 ret->key = GNUNET_CRYPTO_rsa_key_create_from_file (fn);
240 if (ret->key == NULL)
241 {
242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
243 _("Failed to create or read private key for namespace `%s'\n"),
244 name);
245 GNUNET_free (ret);
246 GNUNET_free (fn);
247 return NULL;
248 }
249 ret->filename = fn;
250 return ret;
75} 251}
76 252
77 253
@@ -90,644 +266,114 @@ int
90GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, 266GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace,
91 int freeze) 267 int freeze)
92{ 268{
93 GNUNET_break (0); 269 namespace->rc--;
94 return GNUNET_SYSERR; 270 if (freeze)
95}
96
97
98/**
99 * Build a list of all available local (!) namespaces The returned
100 * names are only the nicknames since we only iterate over the local
101 * namespaces.
102 *
103 * @param h handle to the file sharing subsystem
104 * @param cb function to call on each known namespace
105 * @param cb_cls closure for cb
106 */
107void
108GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h,
109 GNUNET_FS_NamespaceInfoProcessor cb,
110 void *cb_cls)
111{
112 GNUNET_break (0);
113}
114
115/* end of fs_namespace.c */
116
117#if 0
118/*
119 This file is part of GNUnet
120 (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
121
122 GNUnet is free software; you can redistribute it and/or modify
123 it under the terms of the GNU General Public License as published
124 by the Free Software Foundation; either version 2, or (at your
125 option) any later version.
126
127 GNUnet is distributed in the hope that it will be useful, but
128 WITHOUT ANY WARRANTY; without even the implied warranty of
129 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
130 General Public License for more details.
131
132 You should have received a copy of the GNU General Public License
133 along with GNUnet; see the file COPYING. If not, write to the
134 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
135 Boston, MA 02111-1307, USA.
136*/
137
138/**
139 * @file applications/fs/ecrs/namespace.c
140 * @brief creation, deletion and advertising of namespaces
141 * @author Christian Grothoff
142 */
143
144#include "platform.h"
145#include "gnunet_directories.h"
146#include "gnunet_protocols.h"
147#include "gnunet_ecrs_lib.h"
148#include "gnunet_fs_lib.h"
149#include "ecrs_core.h"
150#include "ecrs.h"
151
152#define PSEUDODIR "data/namespace/keys/"
153#define INITVALUE "GNUnet!!"
154#define MAX_SBLOCK_SIZE 32000
155
156static char *
157getPseudonymFileName (struct GNUNET_GE_Context *ectx,
158 struct GNUNET_GC_Configuration *cfg,
159 const GNUNET_HashCode * pid)
160{
161 char *gnHome;
162 char *fileName;
163 GNUNET_EncName enc;
164
165 GNUNET_GC_get_configuration_value_filename (cfg,
166 "GNUNET",
167 "GNUNET_HOME",
168 GNUNET_DEFAULT_HOME_DIRECTORY,
169 &fileName);
170 gnHome = GNUNET_expand_file_name (ectx, fileName);
171 GNUNET_free (fileName);
172 fileName =
173 GNUNET_malloc (strlen (gnHome) + strlen (PSEUDODIR) +
174 sizeof (GNUNET_EncName) + 2);
175 strcpy (fileName, gnHome);
176 GNUNET_free (gnHome);
177 strcat (fileName, DIR_SEPARATOR_STR);
178 strcat (fileName, PSEUDODIR);
179 GNUNET_disk_directory_create (ectx, fileName);
180 if (pid != NULL)
181 {
182 GNUNET_hash_to_enc (pid, &enc);
183 strcat (fileName, (char *) &enc);
184 }
185 return fileName;
186}
187
188
189/**
190 * Check if the given namespace exists (locally).
191 *
192 * @return GNUNET_OK if the namespace exists, GNUNET_SYSERR if not
193 */
194int
195GNUNET_ECRS_namespace_test_exists (struct GNUNET_GE_Context *ectx,
196 struct GNUNET_GC_Configuration *cfg,
197 const GNUNET_HashCode * pid)
198{
199 char *fileName;
200 int ret;
201
202 fileName = getPseudonymFileName (ectx, cfg, pid);
203 ret = GNUNET_disk_file_test (ectx, fileName);
204 GNUNET_free (fileName);
205 return ret;
206}
207
208/**
209 * Delete a local namespace.
210 *
211 * @return GNUNET_OK on success, GNUNET_SYSERR on error
212 */
213int
214GNUNET_ECRS_namespace_delete (struct GNUNET_GE_Context *ectx,
215 struct GNUNET_GC_Configuration *cfg,
216 const GNUNET_HashCode * pid)
217{
218 char *fileName;
219
220 fileName = getPseudonymFileName (ectx, cfg, pid);
221 if (GNUNET_YES != GNUNET_disk_file_test (ectx, fileName))
222 { 271 {
223 GNUNET_free (fileName); 272 if (0 != UNLINK (namespace->filename))
224 return GNUNET_SYSERR; /* no such namespace */ 273 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
274 "unlink",
275 namespace->filename);
225 } 276 }
226 if (0 != UNLINK (fileName)) 277 if (0 == namespace->rc)
227 { 278 {
228 GNUNET_GE_LOG_STRERROR_FILE (ectx, 279 GNUNET_CRYPTO_rsa_key_free (namespace->key);
229 GNUNET_GE_WARNING | GNUNET_GE_USER | 280 GNUNET_free (namespace->filename);
230 GNUNET_GE_BULK, "unlink", fileName); 281 GNUNET_free (namespace);
231 GNUNET_free (fileName);
232 return GNUNET_SYSERR;
233 } 282 }
234 GNUNET_free (fileName);
235 return GNUNET_OK; 283 return GNUNET_OK;
236} 284}
237 285
238/**
239 * Write the private key of the namespace to a file.
240 */
241static int
242write_namespace_key (struct GNUNET_GC_Configuration *cfg,
243 const struct GNUNET_RSA_PrivateKey *key)
244{
245 GNUNET_RSA_PrivateKeyEncoded *namespace_priv_key_encoded;
246 char *fileName;
247 GNUNET_RSA_PublicKey pubk;
248 GNUNET_HashCode pid;
249
250 GNUNET_RSA_get_public_key (key, &pubk);
251 GNUNET_hash (&pubk, sizeof (GNUNET_RSA_PublicKey), &pid);
252 fileName = getPseudonymFileName (NULL, cfg, &pid);
253 if (GNUNET_YES == GNUNET_disk_file_test (NULL, fileName))
254 {
255 GNUNET_GE_BREAK (NULL, 0); /* hash collision!? */
256 GNUNET_free (fileName);
257 return GNUNET_SYSERR;
258 }
259 namespace_priv_key_encoded = GNUNET_RSA_encode_key (key);
260 GNUNET_disk_file_write (NULL, fileName,
261 (const char *) namespace_priv_key_encoded,
262 ntohs (namespace_priv_key_encoded->len), "600");
263 GNUNET_free (fileName);
264 GNUNET_free (namespace_priv_key_encoded);
265 return GNUNET_OK;
266}
267 286
268/** 287/**
269 * Create a new namespace (and publish an advertismement). 288 * Context for the 'process_namespace' callback.
270 * This publishes both an GNUNET_EC_NBlock in the namespace itself 289 * Specifies a function to call on each namespace.
271 * as well as KNBlocks under all keywords specified in
272 * the advertisementURI.
273 *
274 * @param anonymity_level for the namespace advertismement
275 * @param priority for the namespace advertisement
276 * @param expiration for the namespace advertisement
277 * @param advertisementURI the keyword (!) URI to advertise the
278 * namespace under (GNUNET_EC_KNBlock)
279 * @param meta meta-data for the namespace advertisement
280 * (will be used to derive a name)
281 * @param rootEntry name of the root entry in the namespace (for
282 * the namespace advertisement)
283 * @param rootURI set to the URI of the namespace, NULL if
284 * no advertisement was created
285 *
286 * @return URI on success, NULL on error
287 */ 290 */
288struct GNUNET_ECRS_URI * 291struct ProcessNamespaceContext
289GNUNET_ECRS_namespace_create (struct GNUNET_GE_Context *ectx,
290 struct GNUNET_GC_Configuration *cfg,
291 const struct GNUNET_CONTAINER_MetaData *meta,
292 uint32_t anonymityLevel,
293 uint32_t priority,
294 GNUNET_CronTime expiration,
295 const struct GNUNET_ECRS_URI *advertisementURI,
296 const char *rootEntry)
297{
298 struct GNUNET_ECRS_URI *rootURI;
299 struct GNUNET_RSA_PrivateKey *namespace_priv_key;
300 GNUNET_HashCode hc;
301 struct GNUNET_ClientServerConnection *sock;
302 GNUNET_DatastoreValue *value;
303 GNUNET_DatastoreValue *knvalue;
304 unsigned int size;
305 unsigned int mdsize;
306 struct GNUNET_RSA_PrivateKey *pk;
307 GNUNET_EC_SBlock *sb;
308 GNUNET_EC_KSBlock *ksb;
309 char **keywords;
310 const char *keyword;
311 unsigned int keywordCount;
312 int i;
313 char *cpy;
314 char *rtgt;
315
316 if ((advertisementURI != NULL)
317 && (!GNUNET_ECRS_uri_test_ksk (advertisementURI)))
318 {
319 GNUNET_GE_BREAK (ectx, 0);
320 return NULL;
321 }
322 namespace_priv_key = GNUNET_RSA_create_key ();
323 if (GNUNET_OK != write_namespace_key (cfg, namespace_priv_key))
324 {
325 GNUNET_RSA_free_key (namespace_priv_key);
326 return NULL;
327 }
328
329 /* create advertisements */
330 mdsize = GNUNET_meta_data_get_serialized_size (meta, GNUNET_SERIALIZE_PART);
331 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (rootEntry) + 2;
332 if (size > MAX_SBLOCK_SIZE)
333 {
334 size = MAX_SBLOCK_SIZE;
335 mdsize = size - sizeof (GNUNET_EC_SBlock) - strlen (rootEntry) - 2;
336 }
337 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
338 memset (value, 0, sizeof (GNUNET_DatastoreValue) + size);
339 sb = (GNUNET_EC_SBlock *) & value[1];
340 sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
341 GNUNET_RSA_get_public_key (namespace_priv_key, &sb->subspace);
342 rtgt = (char *) &sb[1];
343 memcpy (rtgt, rootEntry, strlen (rootEntry) + 1);
344 mdsize = GNUNET_meta_data_serialize (ectx,
345 meta,
346 &rtgt[strlen (rootEntry) + 2],
347 mdsize, GNUNET_SERIALIZE_PART);
348 if (mdsize == -1)
349 {
350 GNUNET_GE_BREAK (ectx, 0);
351 GNUNET_RSA_free_key (namespace_priv_key);
352 GNUNET_free (value);
353 return NULL;
354 }
355 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (rootEntry) + 2;
356 GNUNET_GE_ASSERT (ectx,
357 GNUNET_OK == GNUNET_RSA_sign (namespace_priv_key,
358 size
359 -
360 sizeof
361 (GNUNET_RSA_Signature) -
362 sizeof
363 (GNUNET_RSA_PublicKey) -
364 sizeof (unsigned int),
365 &sb->identifier,
366 &sb->signature));
367 value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
368 value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
369 value->priority = htonl (priority);
370 value->anonymity_level = htonl (anonymityLevel);
371 value->expiration_time = GNUNET_htonll (expiration);
372 sock = GNUNET_client_connection_create (ectx, cfg);
373 if (sock == NULL)
374 {
375 GNUNET_free (value);
376 GNUNET_RSA_free_key (namespace_priv_key);
377 return NULL;
378 }
379 if (GNUNET_OK != GNUNET_FS_insert (sock, value))
380 {
381 GNUNET_free (value);
382 GNUNET_client_connection_destroy (sock);
383 GNUNET_RSA_free_key (namespace_priv_key);
384 return NULL;
385 }
386
387
388 /* publish KNBlocks */
389 size += sizeof (GNUNET_EC_KSBlock) - sizeof (GNUNET_EC_SBlock);
390 knvalue = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
391 *knvalue = *value;
392 knvalue->type = htonl (GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED);
393 knvalue->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
394 ksb = (GNUNET_EC_KSBlock *) & knvalue[1];
395 ksb->type = htonl (GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED);
396 memcpy (&ksb->sblock,
397 sb, sizeof (GNUNET_EC_SBlock) + mdsize + strlen (rootEntry) + 2);
398
399 if (advertisementURI != NULL)
400 {
401 keywords = advertisementURI->data.ksk.keywords;
402 keywordCount = advertisementURI->data.ksk.keywordCount;
403 cpy =
404 GNUNET_malloc (size - sizeof (GNUNET_EC_KBlock) -
405 sizeof (unsigned int));
406 memcpy (cpy,
407 &ksb->sblock,
408 size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int));
409 for (i = 0; i < keywordCount; i++)
410 {
411 keyword = keywords[i];
412 /* first character of keyword indicates
413 mandatory or not -- ignore for hashing! */
414 GNUNET_hash (&keyword[1], strlen (&keyword[1]), &hc);
415 pk = GNUNET_RSA_create_key_from_hash (&hc);
416 GNUNET_RSA_get_public_key (pk, &ksb->kblock.keyspace);
417 GNUNET_GE_ASSERT (ectx,
418 size - sizeof (GNUNET_EC_KBlock) -
419 sizeof (unsigned int) ==
420 sizeof (GNUNET_EC_SBlock) + mdsize +
421 strlen (rootEntry) + 2);
422 GNUNET_ECRS_encryptInPlace (&hc, &ksb->sblock,
423 size - sizeof (GNUNET_EC_KBlock) -
424 sizeof (unsigned int));
425
426 GNUNET_GE_ASSERT (ectx,
427 GNUNET_OK == GNUNET_RSA_sign (pk,
428 size -
429 sizeof
430 (GNUNET_EC_KBlock) -
431 sizeof (unsigned
432 int),
433 &ksb->sblock,
434 &ksb->
435 kblock.signature));
436 /* extra check: verify sig */
437 GNUNET_RSA_free_key (pk);
438 if (GNUNET_OK != GNUNET_FS_insert (sock, knvalue))
439 {
440 GNUNET_GE_BREAK (ectx, 0);
441 GNUNET_free (cpy);
442 GNUNET_free (knvalue);
443 GNUNET_free (value);
444 GNUNET_client_connection_destroy (sock);
445 GNUNET_RSA_free_key (namespace_priv_key);
446 return NULL;
447 }
448 /* restore nblock to avoid re-encryption! */
449 memcpy (&ksb->sblock,
450 cpy,
451 size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int));
452 }
453 GNUNET_free (cpy);
454 }
455 rootURI = GNUNET_malloc (sizeof (URI));
456 rootURI->type = sks;
457 GNUNET_hash (&sb->subspace,
458 sizeof (GNUNET_RSA_PublicKey), &rootURI->data.sks.namespace);
459 rootURI->data.sks.identifier = GNUNET_strdup (rootEntry);
460 GNUNET_free (knvalue);
461 GNUNET_free (value);
462 GNUNET_client_connection_destroy (sock);
463 GNUNET_RSA_free_key (namespace_priv_key);
464
465 return rootURI;
466}
467
468static struct GNUNET_RSA_PrivateKey *
469read_namespace_key (struct GNUNET_GC_Configuration *cfg,
470 const GNUNET_HashCode * pid)
471{ 292{
472 char *fileName; 293 /**
473 GNUNET_RSA_PrivateKeyEncoded *hke; 294 * Function to call.
474 struct GNUNET_RSA_PrivateKey *hk; 295 */
475 char *dst; 296 GNUNET_FS_NamespaceInfoProcessor cb;
476 unsigned long long len; 297
477 298 /**
478 fileName = getPseudonymFileName (NULL, cfg, pid); 299 * Closure for 'cb'.
479 if (GNUNET_OK != GNUNET_disk_file_size (NULL, fileName, &len, GNUNET_YES)) 300 */
480 { 301 void *cb_cls;
481 GNUNET_free (fileName); 302};
482 return NULL;
483 }
484 if (len < 2)
485 {
486 GNUNET_GE_LOG (NULL, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
487 _("File `%s' does not contain a pseudonym.\n"),
488 fileName);
489 GNUNET_free (fileName);
490 return NULL;
491 }
492 dst = GNUNET_malloc (len);
493 len = GNUNET_disk_file_read (NULL, fileName, len, dst);
494 hke = (GNUNET_RSA_PrivateKeyEncoded *) dst;
495 if (ntohs (hke->len) != len)
496 {
497 GNUNET_GE_LOG (NULL, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
498 _("Format of pseudonym `%s' is invalid.\n"), fileName);
499 GNUNET_free (fileName);
500 GNUNET_free (hke);
501 return NULL;
502 }
503 GNUNET_free (fileName);
504 hk = GNUNET_RSA_decode_key (hke);
505 GNUNET_free (hke);
506 return hk;
507}
508 303
509 304
510/** 305/**
511 * Add an entry into a namespace. 306 * Function called with a filename of a namespace. Reads the key and
307 * calls the callback.
512 * 308 *
513 * @param dstU to which URI should the namespace entry refer? 309 * @param cls closure (struct ProcessNamespaceContext)
514 * @param md what meta-data should be associated with the 310 * @param filename complete filename (absolute path)
515 * entry? 311 * @return GNUNET_OK to continue to iterate,
516 * @param thisId name of this entry in the namespace (keyword/identifier) 312 * GNUNET_SYSERR to abort iteration with error!
517 * @param nextId name of the update for this entry (to be published in
518 * the future; maybe NULL)
519 * @param pid unique identifier of the namespace/pseudonym
520 * @return URI on success, NULL on error
521 */ 313 */
522struct GNUNET_ECRS_URI *
523GNUNET_ECRS_namespace_add_content (struct GNUNET_GE_Context *ectx,
524 struct GNUNET_GC_Configuration *cfg,
525 const GNUNET_HashCode * pid,
526 uint32_t anonymityLevel,
527 uint32_t priority,
528 GNUNET_CronTime expiration,
529 const char *thisId,
530 const char *nextId,
531 const struct GNUNET_ECRS_URI *dstU,
532 const struct GNUNET_MetaData *md)
533{
534 struct GNUNET_ECRS_URI *uri;
535 struct GNUNET_ClientServerConnection *sock;
536 GNUNET_DatastoreValue *value;
537 unsigned int size;
538 unsigned int mdsize;
539 struct GNUNET_RSA_PrivateKey *hk;
540 GNUNET_EC_SBlock *sb;
541 char *dstURI;
542 char *destPos;
543 GNUNET_HashCode hc; /* hash of thisId = key */
544 GNUNET_HashCode hc2; /* hash of hc = identifier */
545 int ret;
546 unsigned int nidlen;
547
548 hk = read_namespace_key (cfg, pid);
549 if (hk == NULL)
550 return NULL;
551
552 /* THEN: construct GNUNET_EC_SBlock */
553 dstURI = GNUNET_ECRS_uri_to_string (dstU);
554 mdsize = GNUNET_meta_data_get_serialized_size (md, GNUNET_SERIALIZE_PART);
555 if (nextId == NULL)
556 nextId = "";
557 nidlen = strlen (nextId) + 1;
558 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen;
559 if (size > MAX_SBLOCK_SIZE)
560 {
561 size = MAX_SBLOCK_SIZE;
562 mdsize =
563 size - (sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen);
564 }
565 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
566 sb = (GNUNET_EC_SBlock *) & value[1];
567 sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
568 destPos = (char *) &sb[1];
569 memcpy (destPos, nextId, nidlen);
570 destPos += nidlen;
571 memcpy (destPos, dstURI, strlen (dstURI) + 1);
572 destPos += strlen (dstURI) + 1;
573 mdsize = GNUNET_meta_data_serialize (ectx,
574 md,
575 destPos,
576 mdsize, GNUNET_SERIALIZE_PART);
577 if (mdsize == -1)
578 {
579 GNUNET_GE_BREAK (ectx, 0);
580 GNUNET_free (dstURI);
581 GNUNET_RSA_free_key (hk);
582 GNUNET_free (value);
583 return NULL;
584 }
585 size = sizeof (GNUNET_EC_SBlock) + mdsize + strlen (dstURI) + 1 + nidlen;
586 value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
587 value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
588 value->priority = htonl (priority);
589 value->anonymity_level = htonl (anonymityLevel);
590 value->expiration_time = GNUNET_htonll (expiration);
591 GNUNET_hash (thisId, strlen (thisId), &hc);
592 GNUNET_hash (&hc, sizeof (GNUNET_HashCode), &hc2);
593 uri = GNUNET_malloc (sizeof (URI));
594 uri->type = sks;
595 GNUNET_RSA_get_public_key (hk, &sb->subspace);
596 GNUNET_hash (&sb->subspace,
597 sizeof (GNUNET_RSA_PublicKey), &uri->data.sks.namespace);
598 GNUNET_GE_BREAK (ectx, 0 == memcmp (&uri->data.sks.namespace,
599 pid, sizeof (GNUNET_HashCode)));
600 uri->data.sks.identifier = GNUNET_strdup (thisId);
601 GNUNET_hash_xor (&hc2, &uri->data.sks.namespace, &sb->identifier);
602 GNUNET_ECRS_encryptInPlace (&hc, &sb[1], size - sizeof (GNUNET_EC_SBlock));
603 GNUNET_GE_ASSERT (ectx,
604 GNUNET_OK == GNUNET_RSA_sign (hk,
605 size
606 -
607 sizeof
608 (GNUNET_RSA_Signature) -
609 sizeof
610 (GNUNET_RSA_PublicKey) -
611 sizeof (unsigned int),
612 &sb->identifier,
613 &sb->signature));
614 GNUNET_RSA_free_key (hk);
615 sock = GNUNET_client_connection_create (ectx, cfg);
616 ret = GNUNET_FS_insert (sock, value);
617 if (ret != GNUNET_OK)
618 {
619 GNUNET_free (uri);
620 uri = NULL;
621 }
622 GNUNET_client_connection_destroy (sock);
623 GNUNET_free (value);
624 GNUNET_free (dstURI);
625
626 return uri;
627}
628
629struct lNCLS
630{
631 struct GNUNET_GE_Context *ectx;
632 struct GNUNET_GC_Configuration *cfg;
633 GNUNET_ECRS_NamespaceInfoProcessor cb;
634 void *cls;
635 int cnt;
636};
637
638static int 314static int
639processFile_ (void *cls, const char *fileName) 315process_namespace (void *cls,
316 const char *filename)
640{ 317{
641 struct lNCLS *c = cls; 318 struct ProcessNamespaceContext *pnc = cls;
642 struct GNUNET_RSA_PrivateKey *hk; 319 struct GNUNET_CRYPTO_RsaPrivateKey *key;
643 GNUNET_RSA_PrivateKeyEncoded *hke; 320 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
644 char *dst; 321 GNUNET_HashCode id;
645 unsigned long long len;
646 GNUNET_HashCode namespace;
647 GNUNET_RSA_PublicKey pk;
648 const char *name; 322 const char *name;
323 const char *t;
649 324
650 if (GNUNET_OK != 325 key = GNUNET_CRYPTO_rsa_key_create_from_file (filename);
651 GNUNET_disk_file_size (c->ectx, fileName, &len, GNUNET_YES)) 326 if (key == NULL)
652 return GNUNET_OK;
653 if (len < 2)
654 {
655 GNUNET_GE_LOG (c->ectx,
656 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
657 _("Format of file `%s' is invalid, trying to remove.\n"),
658 fileName);
659 UNLINK (fileName);
660 return GNUNET_OK;
661 }
662 dst = GNUNET_malloc (len);
663 len = GNUNET_disk_file_read (c->ectx, fileName, len, dst);
664 hke = (GNUNET_RSA_PrivateKeyEncoded *) dst;
665 if (ntohs (hke->len) != len)
666 { 327 {
667 GNUNET_GE_LOG (c->ectx, 328 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
668 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, 329 _("Failed to read namespace private key file `%s', deleting it!\n"),
669 _("Format of file `%s' is invalid, trying to remove.\n"), 330 filename);
670 fileName); 331 if (0 != UNLINK (filename))
671 UNLINK (fileName); 332 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
672 GNUNET_free (hke); 333 "unlink",
334 filename);
673 return GNUNET_OK; 335 return GNUNET_OK;
674 } 336 }
675 hk = GNUNET_RSA_decode_key (hke); 337 GNUNET_CRYPTO_rsa_key_get_public (key, &pk);
676 GNUNET_free (hke); 338 GNUNET_CRYPTO_rsa_key_free (key);
677 if (hk == NULL) 339 GNUNET_CRYPTO_hash (&pk, sizeof(pk), &id);
678 { 340 name = filename;
679 GNUNET_GE_LOG (c->ectx, 341 while (NULL != (t = strstr (name, DIR_SEPARATOR_STR)))
680 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, 342 name = t + 1;
681 _("Format of file `%s' is invalid, trying to remove.\n"), 343 pnc->cb (pnc->cb_cls,
682 fileName); 344 name,
683 UNLINK (fileName); 345 &id);
684 GNUNET_GE_BREAK (c->ectx, 0);
685 return GNUNET_SYSERR;
686 }
687 GNUNET_RSA_get_public_key (hk, &pk);
688 GNUNET_RSA_free_key (hk);
689 GNUNET_hash (&pk, sizeof (GNUNET_RSA_PublicKey), &namespace);
690 if (NULL != c->cb)
691 {
692 name = fileName;
693 while (NULL != strstr (name, DIR_SEPARATOR_STR))
694 name = 1 + strstr (name, DIR_SEPARATOR_STR);
695 if (GNUNET_OK == c->cb (&namespace, name, c->cls))
696 c->cnt++;
697 else
698 c->cnt = GNUNET_SYSERR;
699 }
700 else
701 c->cnt++;
702 return GNUNET_OK; 346 return GNUNET_OK;
703} 347}
704 348
349
705/** 350/**
706 * Build a list of all available namespaces 351 * Build a list of all available local (!) namespaces The returned
352 * names are only the nicknames since we only iterate over the local
353 * namespaces.
707 * 354 *
708 * @param list where to store the names (is allocated, caller frees) 355 * @param h handle to the file sharing subsystem
709 * @return GNUNET_SYSERR on error, otherwise the number of pseudonyms in list 356 * @param cb function to call on each known namespace
357 * @param cb_cls closure for cb
710 */ 358 */
711int 359void
712GNUNET_ECRS_get_namespaces (struct GNUNET_GE_Context *ectx, 360GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h,
713 struct GNUNET_GC_Configuration *cfg, 361 GNUNET_FS_NamespaceInfoProcessor cb,
714 GNUNET_ECRS_NamespaceInfoProcessor cb, void *cls) 362 void *cb_cls)
715{ 363{
716 char *dirName; 364 char *dn;
717 struct lNCLS myCLS; 365 struct ProcessNamespaceContext ctx;
718 366
719 myCLS.cls = cls; 367 dn = get_namespace_directory (h);
720 myCLS.cb = cb; 368 if (dn == NULL)
721 myCLS.cnt = 0; 369 return;
722 myCLS.ectx = ectx; 370 ctx.cb = cb;
723 myCLS.cfg = cfg; 371 ctx.cb_cls = cb_cls;
724 dirName = getPseudonymFileName (ectx, cfg, NULL); 372 GNUNET_DISK_directory_scan (dn,
725 GNUNET_disk_directory_scan (ectx, dirName, &processFile_, &myCLS); 373 &process_namespace,
726 GNUNET_free (dirName); 374 &ctx);
727 return myCLS.cnt; 375 GNUNET_free (dn);
728} 376}
729 377
378/* end of fs_namespace.c */
730 379
731
732/* end of namespace.c */
733#endif
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index db95a6100..634f88801 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -43,16 +43,6 @@
43#define DEBUG_PUBLISH GNUNET_NO 43#define DEBUG_PUBLISH GNUNET_NO
44 44
45/** 45/**
46 * Maximum allowed size for a KBlock.
47 */
48#define MAX_KBLOCK_SIZE 60000
49
50/**
51 * Maximum allowed size for an SBlock.
52 */
53#define MAX_SBLOCK_SIZE 60000
54
55/**
56 * Main function that performs the upload. 46 * Main function that performs the upload.
57 * @param cls "struct GNUNET_FS_PublishContext" identifies the upload 47 * @param cls "struct GNUNET_FS_PublishContext" identifies the upload
58 * @param tc task context 48 * @param tc task context
@@ -1593,4 +1583,128 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
1593} 1583}
1594 1584
1595 1585
1586#if 0
1587
1588/**
1589 * Add an entry into a namespace.
1590 *
1591 * @param dstU to which URI should the namespace entry refer?
1592 * @param md what meta-data should be associated with the
1593 * entry?
1594 * @param thisId name of this entry in the namespace (keyword/identifier)
1595 * @param nextId name of the update for this entry (to be published in
1596 * the future; maybe NULL)
1597 * @param pid unique identifier of the namespace/pseudonym
1598 * @return URI on success, NULL on error
1599 */
1600struct GNUNET_ECRS_URI *
1601GNUNET_ECRS_namespace_add_content (struct GNUNET_GE_Context *ectx,
1602 struct GNUNET_GC_Configuration *cfg,
1603 const GNUNET_HashCode * pid,
1604 uint32_t anonymityLevel,
1605 uint32_t priority,
1606 GNUNET_CronTime expiration,
1607 const char *thisId,
1608 const char *nextId,
1609 const struct GNUNET_ECRS_URI *dstU,
1610 const struct GNUNET_MetaData *md)
1611{
1612 struct GNUNET_ECRS_URI *uri;
1613 struct GNUNET_ClientServerConnection *sock;
1614 GNUNET_DatastoreValue *value;
1615 unsigned int size;
1616 unsigned int mdsize;
1617 struct GNUNET_RSA_PrivateKey *hk;
1618 GNUNET_EC_SBlock *sb;
1619 char *dstURI;
1620 char *destPos;
1621 GNUNET_HashCode hc; /* hash of thisId = key */
1622 GNUNET_HashCode hc2; /* hash of hc = identifier */
1623 int ret;
1624 unsigned int nidlen;
1625
1626 hk = read_namespace_key (cfg, pid);
1627 if (hk == NULL)
1628 return NULL;
1629
1630 /* THEN: construct GNUNET_EC_SBlock */
1631 dstURI = GNUNET_ECRS_uri_to_string (dstU);
1632 mdsize = GNUNET_meta_data_get_serialized_size (md, GNUNET_SERIALIZE_PART);
1633 if (nextId == NULL)
1634 nextId = "";
1635 nidlen = strlen (nextId) + 1;
1636 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen;
1637 if (size > MAX_SBLOCK_SIZE)
1638 {
1639 size = MAX_SBLOCK_SIZE;
1640 mdsize =
1641 size - (sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen);
1642 }
1643 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
1644 sb = (GNUNET_EC_SBlock *) & value[1];
1645 sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
1646 destPos = (char *) &sb[1];
1647 memcpy (destPos, nextId, nidlen);
1648 destPos += nidlen;
1649 memcpy (destPos, dstURI, strlen (dstURI) + 1);
1650 destPos += strlen (dstURI) + 1;
1651 mdsize = GNUNET_meta_data_serialize (ectx,
1652 md,
1653 destPos,
1654 mdsize, GNUNET_SERIALIZE_PART);
1655 if (mdsize == -1)
1656 {
1657 GNUNET_GE_BREAK (ectx, 0);
1658 GNUNET_free (dstURI);
1659 GNUNET_RSA_free_key (hk);
1660 GNUNET_free (value);
1661 return NULL;
1662 }
1663 size = sizeof (GNUNET_EC_SBlock) + mdsize + strlen (dstURI) + 1 + nidlen;
1664 value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
1665 value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
1666 value->priority = htonl (priority);
1667 value->anonymity_level = htonl (anonymityLevel);
1668 value->expiration_time = GNUNET_htonll (expiration);
1669 GNUNET_hash (thisId, strlen (thisId), &hc);
1670 GNUNET_hash (&hc, sizeof (GNUNET_HashCode), &hc2);
1671 uri = GNUNET_malloc (sizeof (URI));
1672 uri->type = sks;
1673 GNUNET_RSA_get_public_key (hk, &sb->subspace);
1674 GNUNET_hash (&sb->subspace,
1675 sizeof (GNUNET_RSA_PublicKey), &uri->data.sks.namespace);
1676 GNUNET_GE_BREAK (ectx, 0 == memcmp (&uri->data.sks.namespace,
1677 pid, sizeof (GNUNET_HashCode)));
1678 uri->data.sks.identifier = GNUNET_strdup (thisId);
1679 GNUNET_hash_xor (&hc2, &uri->data.sks.namespace, &sb->identifier);
1680 GNUNET_ECRS_encryptInPlace (&hc, &sb[1], size - sizeof (GNUNET_EC_SBlock));
1681 GNUNET_GE_ASSERT (ectx,
1682 GNUNET_OK == GNUNET_RSA_sign (hk,
1683 size
1684 -
1685 sizeof
1686 (GNUNET_RSA_Signature) -
1687 sizeof
1688 (GNUNET_RSA_PublicKey) -
1689 sizeof (unsigned int),
1690 &sb->identifier,
1691 &sb->signature));
1692 GNUNET_RSA_free_key (hk);
1693 sock = GNUNET_client_connection_create (ectx, cfg);
1694 ret = GNUNET_FS_insert (sock, value);
1695 if (ret != GNUNET_OK)
1696 {
1697 GNUNET_free (uri);
1698 uri = NULL;
1699 }
1700 GNUNET_client_connection_destroy (sock);
1701 GNUNET_free (value);
1702 GNUNET_free (dstURI);
1703
1704 return uri;
1705}
1706
1707#endif
1708
1709
1596/* end of fs_publish.c */ 1710/* end of fs_publish.c */
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index 70cbd3f84..59fd3022b 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -1847,8 +1847,8 @@ process_reply (void *cls,
1847 1847
1848 } 1848 }
1849 break; 1849 break;
1850 case GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK: 1850 case GNUNET_DATASTORE_BLOCKTYPE_NBLOCK:
1851 // FIXME: any checks against duplicates for SKBlocks? 1851 // FIXME: any checks against duplicates for NBlocks?
1852 break; 1852 break;
1853 default: 1853 default:
1854 GNUNET_break (0); 1854 GNUNET_break (0);
@@ -1996,8 +1996,8 @@ handle_p2p_put (void *cls,
1996 &prq.namespace)) 1996 &prq.namespace))
1997 return GNUNET_SYSERR; 1997 return GNUNET_SYSERR;
1998 break; 1998 break;
1999 case GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK: 1999 case GNUNET_DATASTORE_BLOCKTYPE_NBLOCK:
2000 // FIXME -- validate SKBLOCK! 2000 // FIXME -- validate NBLOCK!
2001 GNUNET_break (0); 2001 GNUNET_break (0);
2002 return GNUNET_OK; 2002 return GNUNET_OK;
2003 default: 2003 default:
@@ -2212,7 +2212,7 @@ process_local_reply (void *cls,
2212 pr->results_found++; 2212 pr->results_found++;
2213 if ( (pr->type == GNUNET_DATASTORE_BLOCKTYPE_KBLOCK) || 2213 if ( (pr->type == GNUNET_DATASTORE_BLOCKTYPE_KBLOCK) ||
2214 (pr->type == GNUNET_DATASTORE_BLOCKTYPE_SBLOCK) || 2214 (pr->type == GNUNET_DATASTORE_BLOCKTYPE_SBLOCK) ||
2215 (pr->type == GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK) ) 2215 (pr->type == GNUNET_DATASTORE_BLOCKTYPE_NBLOCK) )
2216 { 2216 {
2217 if (pr->bf == NULL) 2217 if (pr->bf == NULL)
2218 { 2218 {
diff --git a/src/hello/hello.c b/src/hello/hello.c
index e37ae10e6..dfcc31dc2 100644
--- a/src/hello/hello.c
+++ b/src/hello/hello.c
@@ -510,6 +510,4 @@ GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello,
510 return GNUNET_OK; 510 return GNUNET_OK;
511} 511}
512 512
513
514
515/* end of hello.c */ 513/* end of hello.c */
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index e3e62a143..d7842a519 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -107,8 +107,8 @@ struct GNUNET_PeerIdentity
107/** 107/**
108 * Function called with a filename. 108 * Function called with a filename.
109 * 109 *
110 * @param filename complete filename (absolute path)
111 * @param cls closure 110 * @param cls closure
111 * @param filename complete filename (absolute path)
112 * @return GNUNET_OK to continue to iterate, 112 * @return GNUNET_OK to continue to iterate,
113 * GNUNET_SYSERR to abort iteration with error! 113 * GNUNET_SYSERR to abort iteration with error!
114 */ 114 */
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
index aa35c82ee..a506362f2 100644
--- a/src/include/gnunet_datastore_service.h
+++ b/src/include/gnunet_datastore_service.h
@@ -72,9 +72,9 @@ extern "C"
72#define GNUNET_DATASTORE_BLOCKTYPE_ONDEMAND 5 72#define GNUNET_DATASTORE_BLOCKTYPE_ONDEMAND 5
73 73
74/** 74/**
75 * FIXME. 75 * Type of a block that is used to advertise a namespace.
76 */ 76 */
77#define GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK 6 /* not yet used */ 77#define GNUNET_DATASTORE_BLOCKTYPE_NBLOCK 6
78 78
79 79
80/** 80/**
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 111dcd5ac..fe0394335 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -435,9 +435,9 @@ GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext*
435 */ 435 */
436int 436int
437GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext* ctx, 437GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext* ctx,
438 void *scls, 438 void *scls,
439 const char *option, 439 const char *option,
440 const char *value); 440 const char *value);
441 441
442 442
443 443
@@ -2044,22 +2044,20 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc);
2044 * @param anonymity for the namespace advertismement 2044 * @param anonymity for the namespace advertismement
2045 * @param priority for the namespace advertisement 2045 * @param priority for the namespace advertisement
2046 * @param expiration for the namespace advertisement 2046 * @param expiration for the namespace advertisement
2047 * @param advertisementURI the keyword (!) URI to advertise the 2047 * @param rootEntry name of the root of the namespace
2048 * namespace under (we will create a GNUNET_EC_KNBlock) 2048 * @param cont continuation
2049 * @param rootEntry name of the root entry in the namespace (for 2049 * @param cont_cls closure for cont
2050 * the namespace advertisement)
2051 *
2052 * @return uri of the advertisement
2053 */ 2050 */
2054struct GNUNET_FS_Uri * 2051void
2055GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, 2052GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h,
2056 struct GNUNET_FS_Namespace *namespace, 2053 struct GNUNET_FS_Namespace *namespace,
2057 const struct GNUNET_CONTAINER_MetaData *meta, 2054 const struct GNUNET_CONTAINER_MetaData *meta,
2058 uint32_t anonymity, 2055 uint32_t anonymity,
2059 uint32_t priority, 2056 uint32_t priority,
2060 struct GNUNET_TIME_Absolute expiration, 2057 struct GNUNET_TIME_Absolute expiration,
2061 const struct GNUNET_FS_Uri *advertisementURI, 2058 const char *rootEntry,
2062 const char *rootEntry); 2059 GNUNET_FS_PublishContinuation cont,
2060 void *cont_cls);
2063 2061
2064 2062
2065/** 2063/**
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index d7d116c74..6191c4f7e 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -207,8 +207,6 @@ int
207GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello, 207GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello,
208 struct GNUNET_PeerIdentity *peer); 208 struct GNUNET_PeerIdentity *peer);
209 209
210
211
212/* ifndef GNUNET_HELLO_LIB_H */ 210/* ifndef GNUNET_HELLO_LIB_H */
213#endif 211#endif
214/* end of gnunet_hello_lib.h */ 212/* end of gnunet_hello_lib.h */
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index 29aa36811..8b71bb616 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -77,9 +77,14 @@ extern "C"
77#define GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK 6 77#define GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK 6
78 78
79/** 79/**
80 * Signature of advertisment for a namespace.
81 */
82#define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK 7
83
84/**
80 * 85 *
81 */ 86 */
82#define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 7 87#define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 8
83 88
84 89
85#if 0 /* keep Emacsens' auto-indent happy */ 90#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index b466dfbbe..57f88c980 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -883,7 +883,6 @@ consider_for_advertising (const struct GNUNET_HELLO_Message *hello)
883 peer = find_peer (&pid); 883 peer = find_peer (&pid);
884 if (peer == NULL) 884 if (peer == NULL)
885 peer = make_peer (&pid, hello, GNUNET_NO); 885 peer = make_peer (&pid, hello, GNUNET_NO);
886 // FIXME: check if 'hello' is any different from peer->hello?
887#if DEBUG_TOPOLOGY 886#if DEBUG_TOPOLOGY
888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
889 "Found `%s' from peer `%s' for advertising\n", 888 "Found `%s' from peer `%s' for advertising\n",