diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_message_store.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_message_store.c | 324 |
1 files changed, 205 insertions, 119 deletions
diff --git a/src/messenger/gnunet-service-messenger_message_store.c b/src/messenger/gnunet-service-messenger_message_store.c index e137e9d93..d4bccca5c 100644 --- a/src/messenger/gnunet-service-messenger_message_store.c +++ b/src/messenger/gnunet-service-messenger_message_store.c | |||
@@ -30,7 +30,7 @@ | |||
30 | void | 30 | void |
31 | init_message_store (struct GNUNET_MESSENGER_MessageStore *store) | 31 | init_message_store (struct GNUNET_MESSENGER_MessageStore *store) |
32 | { | 32 | { |
33 | GNUNET_assert(store); | 33 | GNUNET_assert (store); |
34 | 34 | ||
35 | store->storage_messages = NULL; | 35 | store->storage_messages = NULL; |
36 | 36 | ||
@@ -42,6 +42,7 @@ init_message_store (struct GNUNET_MESSENGER_MessageStore *store) | |||
42 | store->write_links = GNUNET_NO; | 42 | store->write_links = GNUNET_NO; |
43 | } | 43 | } |
44 | 44 | ||
45 | |||
45 | static int | 46 | static int |
46 | iterate_destroy_entries (void *cls, | 47 | iterate_destroy_entries (void *cls, |
47 | const struct GNUNET_HashCode *key, | 48 | const struct GNUNET_HashCode *key, |
@@ -49,11 +50,12 @@ iterate_destroy_entries (void *cls, | |||
49 | { | 50 | { |
50 | struct GNUNET_MESSENGER_MessageEntry *entry = value; | 51 | struct GNUNET_MESSENGER_MessageEntry *entry = value; |
51 | 52 | ||
52 | GNUNET_free(entry); | 53 | GNUNET_free (entry); |
53 | 54 | ||
54 | return GNUNET_YES; | 55 | return GNUNET_YES; |
55 | } | 56 | } |
56 | 57 | ||
58 | |||
57 | static int | 59 | static int |
58 | iterate_destroy_messages (void *cls, | 60 | iterate_destroy_messages (void *cls, |
59 | const struct GNUNET_HashCode *key, | 61 | const struct GNUNET_HashCode *key, |
@@ -66,6 +68,7 @@ iterate_destroy_messages (void *cls, | |||
66 | return GNUNET_YES; | 68 | return GNUNET_YES; |
67 | } | 69 | } |
68 | 70 | ||
71 | |||
69 | static int | 72 | static int |
70 | iterate_destroy_links (void *cls, | 73 | iterate_destroy_links (void *cls, |
71 | const struct GNUNET_HashCode *key, | 74 | const struct GNUNET_HashCode *key, |
@@ -73,15 +76,16 @@ iterate_destroy_links (void *cls, | |||
73 | { | 76 | { |
74 | struct GNUNET_HashCode *previous = value; | 77 | struct GNUNET_HashCode *previous = value; |
75 | 78 | ||
76 | GNUNET_free(previous); | 79 | GNUNET_free (previous); |
77 | 80 | ||
78 | return GNUNET_YES; | 81 | return GNUNET_YES; |
79 | } | 82 | } |
80 | 83 | ||
84 | |||
81 | void | 85 | void |
82 | clear_message_store (struct GNUNET_MESSENGER_MessageStore *store) | 86 | clear_message_store (struct GNUNET_MESSENGER_MessageStore *store) |
83 | { | 87 | { |
84 | GNUNET_assert(store); | 88 | GNUNET_assert (store); |
85 | 89 | ||
86 | if (store->storage_messages) | 90 | if (store->storage_messages) |
87 | { | 91 | { |
@@ -90,15 +94,19 @@ clear_message_store (struct GNUNET_MESSENGER_MessageStore *store) | |||
90 | store->storage_messages = NULL; | 94 | store->storage_messages = NULL; |
91 | } | 95 | } |
92 | 96 | ||
93 | GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_destroy_entries, NULL); | 97 | GNUNET_CONTAINER_multihashmap_iterate (store->entries, |
94 | GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_destroy_messages, NULL); | 98 | iterate_destroy_entries, NULL); |
95 | GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_destroy_links, NULL); | 99 | GNUNET_CONTAINER_multihashmap_iterate (store->messages, |
100 | iterate_destroy_messages, NULL); | ||
101 | GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_destroy_links, | ||
102 | NULL); | ||
96 | 103 | ||
97 | GNUNET_CONTAINER_multihashmap_destroy (store->entries); | 104 | GNUNET_CONTAINER_multihashmap_destroy (store->entries); |
98 | GNUNET_CONTAINER_multihashmap_destroy (store->messages); | 105 | GNUNET_CONTAINER_multihashmap_destroy (store->messages); |
99 | GNUNET_CONTAINER_multihashmap_destroy (store->links); | 106 | GNUNET_CONTAINER_multihashmap_destroy (store->links); |
100 | } | 107 | } |
101 | 108 | ||
109 | |||
102 | struct GNUNET_MESSENGER_MessageEntryStorage | 110 | struct GNUNET_MESSENGER_MessageEntryStorage |
103 | { | 111 | { |
104 | struct GNUNET_HashCode hash; | 112 | struct GNUNET_HashCode hash; |
@@ -106,10 +114,12 @@ struct GNUNET_MESSENGER_MessageEntryStorage | |||
106 | }; | 114 | }; |
107 | 115 | ||
108 | #define load_message_store_attribute_failed(file, attribute) \ | 116 | #define load_message_store_attribute_failed(file, attribute) \ |
109 | sizeof(attribute) != GNUNET_DISK_file_read(file, &(attribute), sizeof(attribute)) | 117 | sizeof(attribute) != GNUNET_DISK_file_read (file, &(attribute), \ |
118 | sizeof(attribute)) | ||
110 | 119 | ||
111 | #define save_message_store_attribute_failed(file, attribute) \ | 120 | #define save_message_store_attribute_failed(file, attribute) \ |
112 | sizeof(attribute) != GNUNET_DISK_file_write(file, &(attribute), sizeof(attribute)) | 121 | sizeof(attribute) != GNUNET_DISK_file_write (file, &(attribute), \ |
122 | sizeof(attribute)) | ||
113 | 123 | ||
114 | static void | 124 | static void |
115 | load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, | 125 | load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, |
@@ -117,31 +127,36 @@ load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, | |||
117 | { | 127 | { |
118 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); | 128 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); |
119 | 129 | ||
120 | struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); | 130 | struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, |
131 | GNUNET_DISK_OPEN_READ, | ||
132 | permission); | ||
121 | 133 | ||
122 | if (!entries) | 134 | if (! entries) |
123 | return; | 135 | return; |
124 | 136 | ||
125 | struct GNUNET_MESSENGER_MessageEntryStorage storage; | 137 | struct GNUNET_MESSENGER_MessageEntryStorage storage; |
126 | struct GNUNET_MESSENGER_MessageEntry *entry; | 138 | struct GNUNET_MESSENGER_MessageEntry *entry; |
127 | 139 | ||
128 | memset(&storage, 0, sizeof(storage)); | 140 | memset (&storage, 0, sizeof(storage)); |
129 | 141 | ||
130 | do | 142 | do |
131 | { | 143 | { |
132 | entry = NULL; | 144 | entry = NULL; |
133 | 145 | ||
134 | if ((load_message_store_attribute_failed(entries, storage.hash)) || | 146 | if ((load_message_store_attribute_failed (entries, storage.hash)) || |
135 | (load_message_store_attribute_failed(entries, storage.entry.offset)) || | 147 | (load_message_store_attribute_failed (entries, storage.entry.offset)) || |
136 | (load_message_store_attribute_failed(entries, storage.entry.length))) | 148 | (load_message_store_attribute_failed (entries, storage.entry.length))) |
137 | break; | 149 | break; |
138 | 150 | ||
139 | entry = GNUNET_new(struct GNUNET_MESSENGER_MessageEntry); | 151 | entry = GNUNET_new (struct GNUNET_MESSENGER_MessageEntry); |
140 | 152 | ||
141 | GNUNET_memcpy(entry, &(storage.entry), sizeof(*entry)); | 153 | GNUNET_memcpy (entry, &(storage.entry), sizeof(*entry)); |
142 | 154 | ||
143 | if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries, &(storage.hash))) || | 155 | if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries, |
144 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, &(storage.hash), entry, | 156 | &(storage.hash))) |
157 | || | ||
158 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, | ||
159 | &(storage.hash), entry, | ||
145 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | 160 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) |
146 | { | 161 | { |
147 | store->rewrite_entries = GNUNET_YES; | 162 | store->rewrite_entries = GNUNET_YES; |
@@ -151,11 +166,12 @@ load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, | |||
151 | while (entry); | 166 | while (entry); |
152 | 167 | ||
153 | if (entry) | 168 | if (entry) |
154 | GNUNET_free(entry); | 169 | GNUNET_free (entry); |
155 | 170 | ||
156 | GNUNET_DISK_file_close (entries); | 171 | GNUNET_DISK_file_close (entries); |
157 | } | 172 | } |
158 | 173 | ||
174 | |||
159 | struct GNUNET_MESSENGER_MessageLinkStorage | 175 | struct GNUNET_MESSENGER_MessageLinkStorage |
160 | { | 176 | { |
161 | struct GNUNET_HashCode hash; | 177 | struct GNUNET_HashCode hash; |
@@ -168,51 +184,59 @@ load_message_store_links (struct GNUNET_MESSENGER_MessageStore *store, | |||
168 | { | 184 | { |
169 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); | 185 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); |
170 | 186 | ||
171 | struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); | 187 | struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, |
188 | GNUNET_DISK_OPEN_READ, | ||
189 | permission); | ||
172 | 190 | ||
173 | if (!entries) | 191 | if (! entries) |
174 | return; | 192 | return; |
175 | 193 | ||
176 | struct GNUNET_MESSENGER_MessageLinkStorage storage; | 194 | struct GNUNET_MESSENGER_MessageLinkStorage storage; |
177 | struct GNUNET_MESSENGER_MessageLink *link; | 195 | struct GNUNET_MESSENGER_MessageLink *link; |
178 | 196 | ||
179 | memset(&storage, 0, sizeof(storage)); | 197 | memset (&storage, 0, sizeof(storage)); |
180 | 198 | ||
181 | do | 199 | do |
182 | { | 200 | { |
183 | link = NULL; | 201 | link = NULL; |
184 | 202 | ||
185 | if ((load_message_store_attribute_failed(entries, storage.hash)) || | 203 | if ((load_message_store_attribute_failed (entries, storage.hash)) || |
186 | (load_message_store_attribute_failed(entries, storage.link.multiple)) || | 204 | (load_message_store_attribute_failed (entries, |
187 | (load_message_store_attribute_failed(entries, storage.link.first)) || | 205 | storage.link.multiple)) || |
206 | (load_message_store_attribute_failed (entries, storage.link.first)) || | ||
188 | ((GNUNET_YES == storage.link.multiple) && | 207 | ((GNUNET_YES == storage.link.multiple) && |
189 | (load_message_store_attribute_failed(entries, storage.link.second)))) | 208 | (load_message_store_attribute_failed (entries, storage.link.second)))) |
190 | break; | 209 | break; |
191 | 210 | ||
192 | link = GNUNET_new(struct GNUNET_MESSENGER_MessageLink); | 211 | link = GNUNET_new (struct GNUNET_MESSENGER_MessageLink); |
193 | 212 | ||
194 | GNUNET_memcpy(link, &(storage.link), sizeof(*link)); | 213 | GNUNET_memcpy (link, &(storage.link), sizeof(*link)); |
195 | 214 | ||
196 | if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links, &(storage.hash))) || | 215 | if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links, |
197 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, &(storage.hash), link, | 216 | &(storage.hash))) |
217 | || | ||
218 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, | ||
219 | &(storage.hash), link, | ||
198 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | 220 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) |
199 | break; | 221 | break; |
200 | } | 222 | } |
201 | while (link); | 223 | while (link); |
202 | 224 | ||
203 | if (link) | 225 | if (link) |
204 | GNUNET_free(link); | 226 | GNUNET_free (link); |
205 | 227 | ||
206 | GNUNET_DISK_file_close (entries); | 228 | GNUNET_DISK_file_close (entries); |
207 | } | 229 | } |
208 | 230 | ||
231 | |||
209 | void | 232 | void |
210 | load_message_store (struct GNUNET_MESSENGER_MessageStore *store, | 233 | load_message_store (struct GNUNET_MESSENGER_MessageStore *store, |
211 | const char *directory) | 234 | const char *directory) |
212 | { | 235 | { |
213 | GNUNET_assert((store) && (directory)); | 236 | GNUNET_assert ((store) && (directory)); |
214 | 237 | ||
215 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | 238 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
239 | | GNUNET_DISK_PERM_USER_WRITE); | ||
216 | 240 | ||
217 | if (store->storage_messages) | 241 | if (store->storage_messages) |
218 | GNUNET_DISK_file_close (store->storage_messages); | 242 | GNUNET_DISK_file_close (store->storage_messages); |
@@ -221,30 +245,33 @@ load_message_store (struct GNUNET_MESSENGER_MessageStore *store, | |||
221 | GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); | 245 | GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); |
222 | 246 | ||
223 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | 247 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) |
224 | store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE, permission); | 248 | store->storage_messages = GNUNET_DISK_file_open (filename, |
249 | GNUNET_DISK_OPEN_READWRITE, | ||
250 | permission); | ||
225 | else | 251 | else |
226 | store->storage_messages = NULL; | 252 | store->storage_messages = NULL; |
227 | 253 | ||
228 | GNUNET_free(filename); | 254 | GNUNET_free (filename); |
229 | 255 | ||
230 | if (!store->storage_messages) | 256 | if (! store->storage_messages) |
231 | return; | 257 | return; |
232 | 258 | ||
233 | GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); | 259 | GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); |
234 | 260 | ||
235 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | 261 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) |
236 | load_message_store_entries(store, filename); | 262 | load_message_store_entries (store, filename); |
237 | 263 | ||
238 | GNUNET_free(filename); | 264 | GNUNET_free (filename); |
239 | 265 | ||
240 | GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); | 266 | GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); |
241 | 267 | ||
242 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | 268 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) |
243 | load_message_store_links(store, filename); | 269 | load_message_store_links (store, filename); |
244 | 270 | ||
245 | GNUNET_free(filename); | 271 | GNUNET_free (filename); |
246 | } | 272 | } |
247 | 273 | ||
274 | |||
248 | struct GNUNET_MESSENGER_ClosureMessageSave | 275 | struct GNUNET_MESSENGER_ClosureMessageSave |
249 | { | 276 | { |
250 | struct GNUNET_MESSENGER_MessageStore *store; | 277 | struct GNUNET_MESSENGER_MessageStore *store; |
@@ -261,12 +288,15 @@ iterate_save_entries (void *cls, | |||
261 | struct GNUNET_MESSENGER_MessageEntry *entry = value; | 288 | struct GNUNET_MESSENGER_MessageEntry *entry = value; |
262 | 289 | ||
263 | GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); | 290 | GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); |
264 | GNUNET_DISK_file_write (save->storage, &(entry->offset), sizeof(entry->offset)); | 291 | GNUNET_DISK_file_write (save->storage, &(entry->offset), |
265 | GNUNET_DISK_file_write (save->storage, &(entry->length), sizeof(entry->length)); | 292 | sizeof(entry->offset)); |
293 | GNUNET_DISK_file_write (save->storage, &(entry->length), | ||
294 | sizeof(entry->length)); | ||
266 | 295 | ||
267 | return GNUNET_YES; | 296 | return GNUNET_YES; |
268 | } | 297 | } |
269 | 298 | ||
299 | |||
270 | static int | 300 | static int |
271 | iterate_save_messages (void *cls, | 301 | iterate_save_messages (void *cls, |
272 | const struct GNUNET_HashCode *key, | 302 | const struct GNUNET_HashCode *key, |
@@ -274,36 +304,42 @@ iterate_save_messages (void *cls, | |||
274 | { | 304 | { |
275 | struct GNUNET_MESSENGER_ClosureMessageSave *save = cls; | 305 | struct GNUNET_MESSENGER_ClosureMessageSave *save = cls; |
276 | 306 | ||
277 | if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, key)) | 307 | if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, |
308 | key)) | ||
278 | return GNUNET_YES; | 309 | return GNUNET_YES; |
279 | 310 | ||
280 | struct GNUNET_MESSENGER_Message *message = value; | 311 | struct GNUNET_MESSENGER_Message *message = value; |
281 | struct GNUNET_MESSENGER_MessageEntryStorage storage; | 312 | struct GNUNET_MESSENGER_MessageEntryStorage storage; |
282 | 313 | ||
283 | GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash)); | 314 | GNUNET_memcpy (&(storage.hash), key, sizeof(storage.hash)); |
284 | 315 | ||
285 | storage.entry.length = get_message_size (message, GNUNET_YES); | 316 | storage.entry.length = get_message_size (message, GNUNET_YES); |
286 | storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, 0, GNUNET_DISK_SEEK_END); | 317 | storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, |
318 | 0, GNUNET_DISK_SEEK_END); | ||
287 | 319 | ||
288 | if ((GNUNET_SYSERR == storage.entry.offset) || | 320 | if ((GNUNET_SYSERR == storage.entry.offset) || |
289 | (save_message_store_attribute_failed(save->storage, storage.hash)) || | 321 | (save_message_store_attribute_failed (save->storage, storage.hash)) || |
290 | (save_message_store_attribute_failed(save->storage, storage.entry.offset)) || | 322 | (save_message_store_attribute_failed (save->storage, |
291 | (save_message_store_attribute_failed(save->storage, storage.entry.length))) | 323 | storage.entry.offset)) || |
324 | (save_message_store_attribute_failed (save->storage, | ||
325 | storage.entry.length))) | ||
292 | return GNUNET_YES; | 326 | return GNUNET_YES; |
293 | 327 | ||
294 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Storing message with hash: %s\n", | 328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing message with hash: %s\n", |
295 | GNUNET_h2s (&(storage.hash))); | 329 | GNUNET_h2s (&(storage.hash))); |
296 | 330 | ||
297 | char *buffer = GNUNET_malloc(storage.entry.length); | 331 | char *buffer = GNUNET_malloc (storage.entry.length); |
298 | 332 | ||
299 | encode_message (message, storage.entry.length, buffer, GNUNET_YES); | 333 | encode_message (message, storage.entry.length, buffer, GNUNET_YES); |
300 | 334 | ||
301 | GNUNET_DISK_file_write (save->store->storage_messages, buffer, storage.entry.length); | 335 | GNUNET_DISK_file_write (save->store->storage_messages, buffer, |
336 | storage.entry.length); | ||
302 | 337 | ||
303 | GNUNET_free(buffer); | 338 | GNUNET_free (buffer); |
304 | return GNUNET_YES; | 339 | return GNUNET_YES; |
305 | } | 340 | } |
306 | 341 | ||
342 | |||
307 | static int | 343 | static int |
308 | iterate_save_links (void *cls, | 344 | iterate_save_links (void *cls, |
309 | const struct GNUNET_HashCode *key, | 345 | const struct GNUNET_HashCode *key, |
@@ -313,24 +349,28 @@ iterate_save_links (void *cls, | |||
313 | struct GNUNET_MESSENGER_MessageLink *link = value; | 349 | struct GNUNET_MESSENGER_MessageLink *link = value; |
314 | 350 | ||
315 | GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); | 351 | GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); |
316 | GNUNET_DISK_file_write (save->storage, &(link->multiple), sizeof(link->multiple)); | 352 | GNUNET_DISK_file_write (save->storage, &(link->multiple), |
353 | sizeof(link->multiple)); | ||
317 | GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first)); | 354 | GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first)); |
318 | 355 | ||
319 | if (GNUNET_YES == link->multiple) | 356 | if (GNUNET_YES == link->multiple) |
320 | GNUNET_DISK_file_write (save->storage, &(link->second), sizeof(link->second)); | 357 | GNUNET_DISK_file_write (save->storage, &(link->second), |
358 | sizeof(link->second)); | ||
321 | 359 | ||
322 | return GNUNET_YES; | 360 | return GNUNET_YES; |
323 | } | 361 | } |
324 | 362 | ||
363 | |||
325 | void | 364 | void |
326 | save_message_store (struct GNUNET_MESSENGER_MessageStore *store, | 365 | save_message_store (struct GNUNET_MESSENGER_MessageStore *store, |
327 | const char *directory) | 366 | const char *directory) |
328 | { | 367 | { |
329 | GNUNET_assert((store) && (directory)); | 368 | GNUNET_assert ((store) && (directory)); |
330 | 369 | ||
331 | struct GNUNET_MESSENGER_ClosureMessageSave save; | 370 | struct GNUNET_MESSENGER_ClosureMessageSave save; |
332 | 371 | ||
333 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | 372 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ |
373 | | GNUNET_DISK_PERM_USER_WRITE); | ||
334 | 374 | ||
335 | char *filename; | 375 | char *filename; |
336 | 376 | ||
@@ -340,17 +380,20 @@ save_message_store (struct GNUNET_MESSENGER_MessageStore *store, | |||
340 | GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); | 380 | GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); |
341 | 381 | ||
342 | save.store = store; | 382 | save.store = store; |
343 | save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); | 383 | save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE |
384 | | GNUNET_DISK_OPEN_CREATE, permission); | ||
344 | 385 | ||
345 | GNUNET_free(filename); | 386 | GNUNET_free (filename); |
346 | 387 | ||
347 | if (!save.storage) | 388 | if (! save.storage) |
348 | goto save_entries; | 389 | goto save_entries; |
349 | 390 | ||
350 | if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_SET)) | 391 | if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, |
392 | GNUNET_DISK_SEEK_SET)) | ||
351 | goto close_links; | 393 | goto close_links; |
352 | 394 | ||
353 | GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_save_links, &save); | 395 | GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_save_links, |
396 | &save); | ||
354 | store->write_links = GNUNET_NO; | 397 | store->write_links = GNUNET_NO; |
355 | 398 | ||
356 | close_links: | 399 | close_links: |
@@ -360,22 +403,26 @@ save_entries: | |||
360 | GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); | 403 | GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); |
361 | 404 | ||
362 | save.store = store; | 405 | save.store = store; |
363 | save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); | 406 | save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE |
407 | | GNUNET_DISK_OPEN_CREATE, permission); | ||
364 | 408 | ||
365 | GNUNET_free(filename); | 409 | GNUNET_free (filename); |
366 | 410 | ||
367 | if (!save.storage) | 411 | if (! save.storage) |
368 | return; | 412 | return; |
369 | 413 | ||
370 | if (GNUNET_YES == store->rewrite_entries) | 414 | if (GNUNET_YES == store->rewrite_entries) |
371 | { | 415 | { |
372 | if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_SET)) | 416 | if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, |
417 | GNUNET_DISK_SEEK_SET)) | ||
373 | goto close_entries; | 418 | goto close_entries; |
374 | 419 | ||
375 | GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_save_entries, &save); | 420 | GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_save_entries, |
421 | &save); | ||
376 | store->rewrite_entries = GNUNET_NO; | 422 | store->rewrite_entries = GNUNET_NO; |
377 | } | 423 | } |
378 | else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_END)) | 424 | else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, |
425 | GNUNET_DISK_SEEK_END)) | ||
379 | goto close_entries; | 426 | goto close_entries; |
380 | 427 | ||
381 | if (store->storage_messages) | 428 | if (store->storage_messages) |
@@ -383,14 +430,17 @@ save_entries: | |||
383 | 430 | ||
384 | GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); | 431 | GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); |
385 | 432 | ||
386 | store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, | 433 | store->storage_messages = GNUNET_DISK_file_open (filename, |
434 | GNUNET_DISK_OPEN_READWRITE | ||
435 | | GNUNET_DISK_OPEN_CREATE, | ||
387 | permission); | 436 | permission); |
388 | 437 | ||
389 | GNUNET_free(filename); | 438 | GNUNET_free (filename); |
390 | 439 | ||
391 | if (store->storage_messages) | 440 | if (store->storage_messages) |
392 | { | 441 | { |
393 | GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_save_messages, &save); | 442 | GNUNET_CONTAINER_multihashmap_iterate (store->messages, |
443 | iterate_save_messages, &save); | ||
394 | 444 | ||
395 | GNUNET_DISK_file_sync (store->storage_messages); | 445 | GNUNET_DISK_file_sync (store->storage_messages); |
396 | GNUNET_DISK_file_sync (save.storage); | 446 | GNUNET_DISK_file_sync (save.storage); |
@@ -400,80 +450,94 @@ close_entries: | |||
400 | GNUNET_DISK_file_close (save.storage); | 450 | GNUNET_DISK_file_close (save.storage); |
401 | } | 451 | } |
402 | 452 | ||
453 | |||
403 | int | 454 | int |
404 | contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store, | 455 | contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store, |
405 | const struct GNUNET_HashCode *hash) | 456 | const struct GNUNET_HashCode *hash) |
406 | { | 457 | { |
407 | GNUNET_assert((store) && (hash)); | 458 | GNUNET_assert ((store) && (hash)); |
408 | 459 | ||
409 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->messages, hash)) | 460 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->messages, |
461 | hash)) | ||
410 | return GNUNET_YES; | 462 | return GNUNET_YES; |
411 | 463 | ||
412 | return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash); | 464 | return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash); |
413 | } | 465 | } |
414 | 466 | ||
467 | |||
415 | const struct GNUNET_MESSENGER_Message* | 468 | const struct GNUNET_MESSENGER_Message* |
416 | get_store_message (struct GNUNET_MESSENGER_MessageStore *store, | 469 | get_store_message (struct GNUNET_MESSENGER_MessageStore *store, |
417 | const struct GNUNET_HashCode *hash) | 470 | const struct GNUNET_HashCode *hash) |
418 | { | 471 | { |
419 | GNUNET_assert((store) && (hash)); | 472 | GNUNET_assert ((store) && (hash)); |
420 | 473 | ||
421 | struct GNUNET_MESSENGER_Message *message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash); | 474 | struct GNUNET_MESSENGER_Message *message = GNUNET_CONTAINER_multihashmap_get ( |
475 | store->messages, hash); | ||
422 | 476 | ||
423 | if (message) | 477 | if (message) |
424 | return message; | 478 | return message; |
425 | 479 | ||
426 | if (!store->storage_messages) | 480 | if (! store->storage_messages) |
427 | return NULL; | 481 | return NULL; |
428 | 482 | ||
429 | const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); | 483 | const struct GNUNET_MESSENGER_MessageEntry *entry = |
484 | GNUNET_CONTAINER_multihashmap_get (store->entries, hash); | ||
430 | 485 | ||
431 | if (!entry) | 486 | if (! entry) |
432 | return NULL; | 487 | return NULL; |
433 | 488 | ||
434 | if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) | 489 | if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, |
490 | entry->offset, | ||
491 | GNUNET_DISK_SEEK_SET)) | ||
435 | return message; | 492 | return message; |
436 | 493 | ||
437 | char *buffer = GNUNET_malloc(entry->length); | 494 | char *buffer = GNUNET_malloc (entry->length); |
438 | 495 | ||
439 | if (!buffer) | 496 | if (! buffer) |
440 | return NULL; | 497 | return NULL; |
441 | 498 | ||
442 | if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != entry->length) || | 499 | if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != |
443 | (entry->length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES))) | 500 | entry->length) || |
501 | (entry->length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, | ||
502 | GNUNET_YES))) | ||
444 | goto free_buffer; | 503 | goto free_buffer; |
445 | 504 | ||
446 | message = create_message (GNUNET_MESSENGER_KIND_UNKNOWN); | 505 | message = create_message (GNUNET_MESSENGER_KIND_UNKNOWN); |
447 | 506 | ||
448 | const int decoding = decode_message (message, entry->length, buffer, GNUNET_YES, NULL); | 507 | const int decoding = decode_message (message, entry->length, buffer, |
508 | GNUNET_YES, NULL); | ||
449 | 509 | ||
450 | struct GNUNET_HashCode check; | 510 | struct GNUNET_HashCode check; |
451 | hash_message (message, entry->length, buffer, &check); | 511 | hash_message (message, entry->length, buffer, &check); |
452 | 512 | ||
453 | if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0)) | 513 | if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0)) |
454 | { | 514 | { |
455 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry)) | 515 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries, |
456 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Corrupted entry could not be removed from store: %s\n", | 516 | hash, entry)) |
457 | GNUNET_h2s(hash)); | 517 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
518 | "Corrupted entry could not be removed from store: %s\n", | ||
519 | GNUNET_h2s (hash)); | ||
458 | 520 | ||
459 | store->rewrite_entries = GNUNET_YES; | 521 | store->rewrite_entries = GNUNET_YES; |
460 | 522 | ||
461 | goto free_message; | 523 | goto free_message; |
462 | } | 524 | } |
463 | 525 | ||
464 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, | 526 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, |
527 | message, | ||
465 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 528 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
466 | goto free_buffer; | 529 | goto free_buffer; |
467 | 530 | ||
468 | free_message: destroy_message (message); | 531 | free_message : destroy_message (message); |
469 | message = NULL; | 532 | message = NULL; |
470 | 533 | ||
471 | free_buffer: | 534 | free_buffer: |
472 | GNUNET_free(buffer); | 535 | GNUNET_free (buffer); |
473 | 536 | ||
474 | return message; | 537 | return message; |
475 | } | 538 | } |
476 | 539 | ||
540 | |||
477 | const struct GNUNET_MESSENGER_MessageLink* | 541 | const struct GNUNET_MESSENGER_MessageLink* |
478 | get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, | 542 | get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, |
479 | const struct GNUNET_HashCode *hash, | 543 | const struct GNUNET_HashCode *hash, |
@@ -482,21 +546,26 @@ get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, | |||
482 | if (deleted_only) | 546 | if (deleted_only) |
483 | goto get_link; | 547 | goto get_link; |
484 | 548 | ||
485 | const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash); | 549 | const struct GNUNET_MESSENGER_Message *message = get_store_message (store, |
550 | hash); | ||
486 | 551 | ||
487 | if (!message) | 552 | if (! message) |
488 | goto get_link; | 553 | goto get_link; |
489 | 554 | ||
490 | static struct GNUNET_MESSENGER_MessageLink link; | 555 | static struct GNUNET_MESSENGER_MessageLink link; |
491 | 556 | ||
492 | GNUNET_memcpy(&(link.first), &(message->header.previous), sizeof(link.first)); | 557 | GNUNET_memcpy (&(link.first), &(message->header.previous), |
558 | sizeof(link.first)); | ||
493 | 559 | ||
494 | link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO; | 560 | link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? |
561 | GNUNET_YES : GNUNET_NO; | ||
495 | 562 | ||
496 | if (GNUNET_YES == link.multiple) | 563 | if (GNUNET_YES == link.multiple) |
497 | GNUNET_memcpy(&(link.second), &(message->body.merge.previous), sizeof(link.second)); | 564 | GNUNET_memcpy (&(link.second), &(message->body.merge.previous), |
565 | sizeof(link.second)); | ||
498 | else | 566 | else |
499 | GNUNET_memcpy(&(link.second), &(message->header.previous), sizeof(link.second)); | 567 | GNUNET_memcpy (&(link.second), &(message->header.previous), |
568 | sizeof(link.second)); | ||
500 | 569 | ||
501 | return &link; | 570 | return &link; |
502 | 571 | ||
@@ -504,78 +573,95 @@ get_link: | |||
504 | return GNUNET_CONTAINER_multihashmap_get (store->links, hash); | 573 | return GNUNET_CONTAINER_multihashmap_get (store->links, hash); |
505 | } | 574 | } |
506 | 575 | ||
576 | |||
507 | int | 577 | int |
508 | put_store_message (struct GNUNET_MESSENGER_MessageStore *store, | 578 | put_store_message (struct GNUNET_MESSENGER_MessageStore *store, |
509 | const struct GNUNET_HashCode *hash, | 579 | const struct GNUNET_HashCode *hash, |
510 | struct GNUNET_MESSENGER_Message *message) | 580 | struct GNUNET_MESSENGER_Message *message) |
511 | { | 581 | { |
512 | GNUNET_assert((store) && (hash) && (message)); | 582 | GNUNET_assert ((store) && (hash) && (message)); |
513 | 583 | ||
514 | return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, | 584 | return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, |
515 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 585 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
516 | } | 586 | } |
517 | 587 | ||
588 | |||
518 | static void | 589 | static void |
519 | add_link (struct GNUNET_MESSENGER_MessageStore *store, | 590 | add_link (struct GNUNET_MESSENGER_MessageStore *store, |
520 | const struct GNUNET_HashCode *hash, | 591 | const struct GNUNET_HashCode *hash, |
521 | const struct GNUNET_MESSENGER_Message *message) | 592 | const struct GNUNET_MESSENGER_Message *message) |
522 | { | 593 | { |
523 | struct GNUNET_MESSENGER_MessageLink *link = GNUNET_new(struct GNUNET_MESSENGER_MessageLink); | 594 | struct GNUNET_MESSENGER_MessageLink *link = GNUNET_new (struct |
595 | GNUNET_MESSENGER_MessageLink); | ||
524 | 596 | ||
525 | GNUNET_memcpy(&(link->first), &(message->header.previous), sizeof(link->first)); | 597 | GNUNET_memcpy (&(link->first), &(message->header.previous), |
598 | sizeof(link->first)); | ||
526 | 599 | ||
527 | link->multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO; | 600 | link->multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? |
601 | GNUNET_YES : GNUNET_NO; | ||
528 | 602 | ||
529 | if (GNUNET_YES == link->multiple) | 603 | if (GNUNET_YES == link->multiple) |
530 | GNUNET_memcpy(&(link->second), &(message->body.merge.previous), sizeof(link->second)); | 604 | GNUNET_memcpy (&(link->second), &(message->body.merge.previous), |
605 | sizeof(link->second)); | ||
531 | else | 606 | else |
532 | GNUNET_memcpy(&(link->second), &(message->header.previous), sizeof(link->second)); | 607 | GNUNET_memcpy (&(link->second), &(message->header.previous), |
608 | sizeof(link->second)); | ||
533 | 609 | ||
534 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->links, hash, link, | 610 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, hash, link, |
535 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | 611 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) |
536 | GNUNET_free(link); | 612 | GNUNET_free (link); |
537 | } | 613 | } |
538 | 614 | ||
615 | |||
539 | int | 616 | int |
540 | delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, | 617 | delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, |
541 | const struct GNUNET_HashCode *hash) | 618 | const struct GNUNET_HashCode *hash) |
542 | { | 619 | { |
543 | GNUNET_assert((store) && (hash)); | 620 | GNUNET_assert ((store) && (hash)); |
544 | 621 | ||
545 | const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); | 622 | const struct GNUNET_MESSENGER_MessageEntry *entry = |
623 | GNUNET_CONTAINER_multihashmap_get (store->entries, hash); | ||
546 | 624 | ||
547 | if (!entry) | 625 | if (! entry) |
548 | goto clear_memory; | 626 | goto clear_memory; |
549 | 627 | ||
550 | const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash); | 628 | const struct GNUNET_MESSENGER_Message *message = get_store_message (store, |
629 | hash); | ||
551 | 630 | ||
552 | if (message) | 631 | if (message) |
553 | add_link (store, hash, message); | 632 | add_link (store, hash, message); |
554 | 633 | ||
555 | if (!store->storage_messages) | 634 | if (! store->storage_messages) |
556 | goto clear_entry; | 635 | goto clear_entry; |
557 | 636 | ||
558 | if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) | 637 | if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, |
638 | entry->offset, | ||
639 | GNUNET_DISK_SEEK_SET)) | ||
559 | return GNUNET_SYSERR; | 640 | return GNUNET_SYSERR; |
560 | 641 | ||
561 | char *clear_buffer = GNUNET_malloc(entry->length); | 642 | char *clear_buffer = GNUNET_malloc (entry->length); |
562 | 643 | ||
563 | if (!clear_buffer) | 644 | if (! clear_buffer) |
564 | return GNUNET_SYSERR; | 645 | return GNUNET_SYSERR; |
565 | 646 | ||
566 | GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length); | 647 | GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length); |
567 | 648 | ||
568 | if ((entry->length != GNUNET_DISK_file_write (store->storage_messages, clear_buffer, entry->length)) || (GNUNET_OK | 649 | if ((entry->length != GNUNET_DISK_file_write (store->storage_messages, |
569 | != GNUNET_DISK_file_sync (store->storage_messages))) | 650 | clear_buffer, entry->length)) || |
651 | (GNUNET_OK | ||
652 | != | ||
653 | GNUNET_DISK_file_sync ( | ||
654 | store->storage_messages))) | ||
570 | { | 655 | { |
571 | GNUNET_free(clear_buffer); | 656 | GNUNET_free (clear_buffer); |
572 | return GNUNET_SYSERR; | 657 | return GNUNET_SYSERR; |
573 | } | 658 | } |
574 | 659 | ||
575 | GNUNET_free(clear_buffer); | 660 | GNUNET_free (clear_buffer); |
576 | 661 | ||
577 | clear_entry: | 662 | clear_entry: |
578 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry)) | 663 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, |
664 | entry)) | ||
579 | store->rewrite_entries = GNUNET_YES; | 665 | store->rewrite_entries = GNUNET_YES; |
580 | 666 | ||
581 | clear_memory: | 667 | clear_memory: |