aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-09-24 11:58:31 +0000
committerChristian Grothoff <christian@grothoff.org>2016-09-24 11:58:31 +0000
commit3bca0a62abc14e5fe36e1c80ff487e0051dad562 (patch)
tree25a9dc36162d498910f6e41aa85a0d3863e0c1c0 /src/peerstore
parentd02c15600b668a30e091d2c5c59d918bb1e4fee7 (diff)
downloadgnunet-3bca0a62abc14e5fe36e1c80ff487e0051dad562.tar.gz
gnunet-3bca0a62abc14e5fe36e1c80ff487e0051dad562.zip
migrate peerstore to new service MQ API
Diffstat (limited to 'src/peerstore')
-rw-r--r--src/peerstore/gnunet-service-peerstore.c540
-rw-r--r--src/peerstore/peerstore.h7
-rw-r--r--src/peerstore/peerstore_api.c20
-rw-r--r--src/peerstore/peerstore_common.c94
-rw-r--r--src/peerstore/peerstore_common.h38
-rw-r--r--src/peerstore/test_peerstore_api_watch.c53
6 files changed, 356 insertions, 396 deletions
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c
index a074d132a..07cf78dac 100644
--- a/src/peerstore/gnunet-service-peerstore.c
+++ b/src/peerstore/gnunet-service-peerstore.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2014, 2015 GNUnet e.V. 3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
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
@@ -29,26 +29,6 @@
29#include "gnunet_peerstore_plugin.h" 29#include "gnunet_peerstore_plugin.h"
30#include "peerstore_common.h" 30#include "peerstore_common.h"
31 31
32/**
33 * Connected client entry
34 */
35struct ClientEntry
36{
37 /**
38 * DLL.
39 */
40 struct ClientEntry *next;
41
42 /**
43 * DLL.
44 */
45 struct ClientEntry *prev;
46
47 /**
48 * Corresponding server handle.
49 */
50 struct GNUNET_SERVER_Client *client;
51};
52 32
53/** 33/**
54 * Interval for expired records cleanup (in seconds) 34 * Interval for expired records cleanup (in seconds)
@@ -76,21 +56,6 @@ static struct GNUNET_PEERSTORE_PluginFunctions *db;
76static struct GNUNET_CONTAINER_MultiHashMap *watchers; 56static struct GNUNET_CONTAINER_MultiHashMap *watchers;
77 57
78/** 58/**
79 * Our notification context.
80 */
81static struct GNUNET_SERVER_NotificationContext *nc;
82
83/**
84 * Head of linked list of connected clients
85 */
86static struct ClientEntry *client_head;
87
88/**
89 * Tail of linked list of connected clients
90 */
91static struct ClientEntry *client_tail;
92
93/**
94 * Task run to clean up expired records. 59 * Task run to clean up expired records.
95 */ 60 */
96static struct GNUNET_SCHEDULER_Task *expire_task; 61static struct GNUNET_SCHEDULER_Task *expire_task;
@@ -101,6 +66,12 @@ static struct GNUNET_SCHEDULER_Task *expire_task;
101static int in_shutdown; 66static int in_shutdown;
102 67
103/** 68/**
69 * Number of connected clients.
70 */
71static unsigned int num_clients;
72
73
74/**
104 * Perform the actual shutdown operations 75 * Perform the actual shutdown operations
105 */ 76 */
106static void 77static void
@@ -108,15 +79,12 @@ do_shutdown ()
108{ 79{
109 if (NULL != db_lib_name) 80 if (NULL != db_lib_name)
110 { 81 {
111 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, db)); 82 GNUNET_break (NULL ==
83 GNUNET_PLUGIN_unload (db_lib_name,
84 db));
112 GNUNET_free (db_lib_name); 85 GNUNET_free (db_lib_name);
113 db_lib_name = NULL; 86 db_lib_name = NULL;
114 } 87 }
115 if (NULL != nc)
116 {
117 GNUNET_SERVER_notification_context_destroy (nc);
118 nc = NULL;
119 }
120 if (NULL != watchers) 88 if (NULL != watchers)
121 { 89 {
122 GNUNET_CONTAINER_multihashmap_destroy (watchers); 90 GNUNET_CONTAINER_multihashmap_destroy (watchers);
@@ -140,14 +108,15 @@ static void
140shutdown_task (void *cls) 108shutdown_task (void *cls)
141{ 109{
142 in_shutdown = GNUNET_YES; 110 in_shutdown = GNUNET_YES;
143 if (NULL == client_head) /* Only when no connected clients. */ 111 if (0 == num_clients) /* Only when no connected clients. */
144 do_shutdown (); 112 do_shutdown ();
145} 113}
146 114
147 115
148/* Forward declaration */ 116/* Forward declaration */
149static void 117static void
150expire_records_continuation (void *cls, int success); 118expire_records_continuation (void *cls,
119 int success);
151 120
152 121
153/** 122/**
@@ -160,15 +129,18 @@ cleanup_expired_records (void *cls)
160 129
161 expire_task = NULL; 130 expire_task = NULL;
162 GNUNET_assert (NULL != db); 131 GNUNET_assert (NULL != db);
163 ret = db->expire_records (db->cls, GNUNET_TIME_absolute_get (), 132 ret = db->expire_records (db->cls,
164 &expire_records_continuation, NULL); 133 GNUNET_TIME_absolute_get (),
134 &expire_records_continuation,
135 NULL);
165 if (GNUNET_OK != ret) 136 if (GNUNET_OK != ret)
166 { 137 {
167 GNUNET_assert (NULL == expire_task); 138 GNUNET_assert (NULL == expire_task);
168 expire_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 139 expire_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
169 (GNUNET_TIME_UNIT_SECONDS, 140 (GNUNET_TIME_UNIT_SECONDS,
170 EXPIRED_RECORDS_CLEANUP_INTERVAL), 141 EXPIRED_RECORDS_CLEANUP_INTERVAL),
171 &cleanup_expired_records, NULL); 142 &cleanup_expired_records,
143 NULL);
172 } 144 }
173} 145}
174 146
@@ -191,23 +163,49 @@ expire_records_continuation (void *cls,
191 expire_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 163 expire_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
192 (GNUNET_TIME_UNIT_SECONDS, 164 (GNUNET_TIME_UNIT_SECONDS,
193 EXPIRED_RECORDS_CLEANUP_INTERVAL), 165 EXPIRED_RECORDS_CLEANUP_INTERVAL),
194 &cleanup_expired_records, NULL); 166 &cleanup_expired_records,
167 NULL);
168}
169
170
171/**
172 * A client disconnected. Remove all of its data structure entries.
173 *
174 * @param cls closure, NULL
175 * @param client identification of the client
176 * @param mq the message queue
177 * @return
178 */
179static void *
180client_connect_cb (void *cls,
181 struct GNUNET_SERVICE_Client *client,
182 struct GNUNET_MQ_Handle *mq)
183{
184 num_clients++;
185 return client;
195} 186}
196 187
197 188
198/** 189/**
199 * Search for a disconnected client and remove it 190 * Search for a disconnected client and remove it
200 * 191 *
201 * @param cls closuer, a 'struct GNUNET_PEERSTORE_Record *' 192 * @param cls closuer, a `struct GNUNET_SERVICE_Client`
202 * @param key hash of record key 193 * @param key hash of record key
203 * @param value the watcher client, a 'struct GNUNET_SERVER_Client *' 194 * @param value the watcher client, a `struct GNUNET_SERVICE_Client *`
204 * @return #GNUNET_OK to continue iterating 195 * @return #GNUNET_OK to continue iterating
205 */ 196 */
206static int 197static int
207client_disconnect_it (void *cls, const struct GNUNET_HashCode *key, void *value) 198client_disconnect_it (void *cls,
199 const struct GNUNET_HashCode *key,
200 void *value)
208{ 201{
209 if (cls == value) 202 if (value == cls)
210 GNUNET_CONTAINER_multihashmap_remove (watchers, key, value); 203 {
204 GNUNET_CONTAINER_multihashmap_remove (watchers,
205 key,
206 value);
207 num_clients++;
208 }
211 return GNUNET_OK; 209 return GNUNET_OK;
212} 210}
213 211
@@ -219,26 +217,19 @@ client_disconnect_it (void *cls, const struct GNUNET_HashCode *key, void *value)
219 * @param client identification of the client 217 * @param client identification of the client
220 */ 218 */
221static void 219static void
222handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) 220client_disconnect_cb (void *cls,
221 struct GNUNET_SERVICE_Client *client,
222 void *app_cls)
223{ 223{
224 struct ClientEntry *ce; 224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
225 225 "A client disconnected, cleaning up.\n");
226 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "A client disconnected, cleaning up.\n");
227 if (NULL != watchers) 226 if (NULL != watchers)
228 GNUNET_CONTAINER_multihashmap_iterate (watchers, &client_disconnect_it, 227 GNUNET_CONTAINER_multihashmap_iterate (watchers,
228 &client_disconnect_it,
229 client); 229 client);
230 ce = client_head; 230 num_clients--;
231 while (ce != NULL) 231 if ( (0 == num_clients) &&
232 { 232 in_shutdown)
233 if (ce->client == client)
234 {
235 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce);
236 GNUNET_free (ce);
237 break;
238 }
239 ce = ce->next;
240 }
241 if (NULL == client_head && in_shutdown)
242 do_shutdown (); 233 do_shutdown ();
243} 234}
244 235
@@ -252,36 +243,40 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
252 * @return #GNUNET_YES to continue iteration 243 * @return #GNUNET_YES to continue iteration
253 */ 244 */
254static void 245static void
255record_iterator (void *cls, const struct GNUNET_PEERSTORE_Record *record, 246record_iterator (void *cls,
247 const struct GNUNET_PEERSTORE_Record *record,
256 const char *emsg) 248 const char *emsg)
257{ 249{
258 struct GNUNET_PEERSTORE_Record *cls_record = cls; 250 struct GNUNET_PEERSTORE_Record *cls_record = cls;
259 struct StoreRecordMessage *srm; 251 struct GNUNET_MQ_Envelope *env;
260 252
261 if (NULL == record) 253 if (NULL == record)
262 { 254 {
263 /* No more records */ 255 /* No more records */
264 struct GNUNET_MessageHeader endmsg; 256 struct GNUNET_MessageHeader *endmsg;
265 257
266 endmsg.size = htons (sizeof (struct GNUNET_MessageHeader)); 258 env = GNUNET_MQ_msg (endmsg,
267 endmsg.type = htons (GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END); 259 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END);
268 GNUNET_SERVER_notification_context_unicast (nc, cls_record->client, &endmsg, 260 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cls_record->client),
269 GNUNET_NO); 261 env);
270 GNUNET_SERVER_receive_done (cls_record->client, 262 if (NULL == emsg)
271 NULL == emsg ? GNUNET_OK : GNUNET_SYSERR); 263 GNUNET_SERVICE_client_continue (cls_record->client);
264 else
265 GNUNET_SERVICE_client_drop (cls_record->client);
272 PEERSTORE_destroy_record (cls_record); 266 PEERSTORE_destroy_record (cls_record);
273 return; 267 return;
274 } 268 }
275 269
276 srm = 270 env = PEERSTORE_create_record_mq_envelope (record->sub_system,
277 PEERSTORE_create_record_message (record->sub_system, record->peer, 271 record->peer,
278 record->key, record->value, 272 record->key,
279 record->value_size, record->expiry, 273 record->value,
280 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_RECORD); 274 record->value_size,
281 GNUNET_SERVER_notification_context_unicast (nc, cls_record->client, 275 record->expiry,
282 (struct GNUNET_MessageHeader *) 276 0,
283 srm, GNUNET_NO); 277 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_RECORD);
284 GNUNET_free (srm); 278 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cls_record->client),
279 env);
285} 280}
286 281
287 282
@@ -289,28 +284,32 @@ record_iterator (void *cls, const struct GNUNET_PEERSTORE_Record *record,
289 * Iterator over all watcher clients 284 * Iterator over all watcher clients
290 * to notify them of a new record 285 * to notify them of a new record
291 * 286 *
292 * @param cls closuer, a 'struct GNUNET_PEERSTORE_Record *' 287 * @param cls closure, a `struct GNUNET_PEERSTORE_Record *`
293 * @param key hash of record key 288 * @param key hash of record key
294 * @param value the watcher client, a 'struct GNUNET_SERVER_Client *' 289 * @param value the watcher client, a `struct GNUNET_SERVICE_Client *`
295 * @return #GNUNET_YES to continue iterating 290 * @return #GNUNET_YES to continue iterating
296 */ 291 */
297static int 292static int
298watch_notifier_it (void *cls, const struct GNUNET_HashCode *key, void *value) 293watch_notifier_it (void *cls,
294 const struct GNUNET_HashCode *key,
295 void *value)
299{ 296{
300 struct GNUNET_PEERSTORE_Record *record = cls; 297 struct GNUNET_PEERSTORE_Record *record = cls;
301 struct GNUNET_SERVER_Client *client = value; 298 struct GNUNET_SERVICE_Client *client = value;
302 struct StoreRecordMessage *srm; 299 struct GNUNET_MQ_Envelope *env;
303 300
304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found a watcher to update.\n"); 301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
305 srm = 302 "Found a watcher to update.\n");
306 PEERSTORE_create_record_message (record->sub_system, record->peer, 303 env = PEERSTORE_create_record_mq_envelope (record->sub_system,
307 record->key, record->value, 304 record->peer,
308 record->value_size, record->expiry, 305 record->key,
309 GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_RECORD); 306 record->value,
310 GNUNET_SERVER_notification_context_unicast (nc, client, 307 record->value_size,
311 (const struct GNUNET_MessageHeader 308 record->expiry,
312 *) srm, GNUNET_NO); 309 0,
313 GNUNET_free (srm); 310 GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_RECORD);
311 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
312 env);
314 return GNUNET_YES; 313 return GNUNET_YES;
315} 314}
316 315
@@ -325,96 +324,127 @@ watch_notifier (struct GNUNET_PEERSTORE_Record *record)
325{ 324{
326 struct GNUNET_HashCode keyhash; 325 struct GNUNET_HashCode keyhash;
327 326
328 PEERSTORE_hash_key (record->sub_system, record->peer, record->key, &keyhash); 327 PEERSTORE_hash_key (record->sub_system,
329 GNUNET_CONTAINER_multihashmap_get_multiple (watchers, &keyhash, 328 record->peer,
330 &watch_notifier_it, record); 329 record->key,
330 &keyhash);
331 GNUNET_CONTAINER_multihashmap_get_multiple (watchers,
332 &keyhash,
333 &watch_notifier_it,
334 record);
331} 335}
332 336
333 337
334/** 338/**
335 * Handle a watch cancel request from client 339 * Handle a watch cancel request from client
336 * 340 *
337 * @param cls unused 341 * @param cls identification of the client
338 * @param client identification of the client 342 * @param hm the actual message
339 * @param message the actual message
340 */ 343 */
341static void 344static void
342handle_watch_cancel (void *cls, struct GNUNET_SERVER_Client *client, 345handle_watch_cancel (void *cls,
343 const struct GNUNET_MessageHeader *message) 346 const struct StoreKeyHashMessage *hm)
344{ 347{
345 struct StoreKeyHashMessage *hm; 348 struct GNUNET_SERVICE_Client *client = cls;
346 349
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a watch cancel request.\n"); 350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
348 hm = (struct StoreKeyHashMessage *) message; 351 "Received a watch cancel request.\n");
349 GNUNET_CONTAINER_multihashmap_remove (watchers, &hm->keyhash, client); 352 if (GNUNET_OK !=
350 GNUNET_SERVER_receive_done (client, GNUNET_OK); 353 GNUNET_CONTAINER_multihashmap_remove (watchers,
354 &hm->keyhash,
355 client))
356 {
357 GNUNET_break (0);
358 GNUNET_SERVICE_client_drop (client);
359 return;
360 }
361 num_clients++;
362 GNUNET_SERVICE_client_continue (client);
351} 363}
352 364
353 365
354/** 366/**
355 * Handle a watch request from client 367 * Handle a watch request from client
356 * 368 *
357 * @param cls unused 369 * @param cls identification of the client
358 * @param client identification of the client 370 * @param hm the actual message
359 * @param message the actual message
360 */ 371 */
361static void 372static void
362handle_watch (void *cls, struct GNUNET_SERVER_Client *client, 373handle_watch (void *cls,
363 const struct GNUNET_MessageHeader *message) 374 const struct StoreKeyHashMessage *hm)
364{ 375{
365 struct StoreKeyHashMessage *hm; 376 struct GNUNET_SERVICE_Client *client = cls;
366 377
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a watch request.\n"); 378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
368 hm = (struct StoreKeyHashMessage *) message; 379 "Received a watch request.\n");
369 GNUNET_SERVER_client_mark_monitor (client); 380 num_clients--; /* do not count watchers */
370 GNUNET_SERVER_notification_context_add (nc, client); 381 GNUNET_SERVICE_client_mark_monitor (client);
371 GNUNET_CONTAINER_multihashmap_put (watchers, &hm->keyhash, client, 382 GNUNET_CONTAINER_multihashmap_put (watchers,
383 &hm->keyhash,
384 client,
372 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 385 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
373 GNUNET_SERVER_receive_done (client, GNUNET_OK); 386 GNUNET_SERVICE_client_continue (client);
374} 387}
375 388
376 389
377/** 390/**
378 * Handle an iterate request from client 391 * Check an iterate request from client
379 * 392 *
380 * @param cls unused 393 * @param cls client identification of the client
381 * @param client identification of the client 394 * @param srm the actual message
382 * @param message the actual message 395 * @return #GNUNET_OK if @a srm is well-formed
383 */ 396 */
384static void 397static int
385handle_iterate (void *cls, struct GNUNET_SERVER_Client *client, 398check_iterate (void *cls,
386 const struct GNUNET_MessageHeader *message) 399 const struct StoreRecordMessage *srm)
387{ 400{
388 struct GNUNET_PEERSTORE_Record *record; 401 struct GNUNET_PEERSTORE_Record *record;
389 402
390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received an iterate request.\n"); 403 record = PEERSTORE_parse_record_message (srm);
391 record = PEERSTORE_parse_record_message (message);
392 if (NULL == record) 404 if (NULL == record)
393 { 405 {
394 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Malformed iterate request.\n")); 406 GNUNET_break (0);
395 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 407 return GNUNET_SYSERR;
396 return;
397 } 408 }
398 if (NULL == record->sub_system) 409 if (NULL == record->sub_system)
399 { 410 {
400 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 411 GNUNET_break (0);
401 _("Sub system not supplied in client iterate request.\n"));
402 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
403 PEERSTORE_destroy_record (record); 412 PEERSTORE_destroy_record (record);
404 return; 413 return GNUNET_SYSERR;
405 } 414 }
415 return GNUNET_OK;
416}
417
418
419/**
420 * Handle an iterate request from client
421 *
422 * @param cls identification of the client
423 * @param srm the actual message
424 */
425static void
426handle_iterate (void *cls,
427 const struct StoreRecordMessage *srm)
428{
429 struct GNUNET_SERVICE_Client *client = cls;
430 struct GNUNET_PEERSTORE_Record *record;
431
432 record = PEERSTORE_parse_record_message (srm);
406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
407 "Iterate request: ss `%s', peer `%s', key `%s'\n", 434 "Iterate request: ss `%s', peer `%s', key `%s'\n",
408 record->sub_system, 435 record->sub_system,
409 (NULL == record->peer) ? "NULL" : GNUNET_i2s (record->peer), 436 (NULL == record->peer) ? "NULL" : GNUNET_i2s (record->peer),
410 (NULL == record->key) ? "NULL" : record->key); 437 (NULL == record->key) ? "NULL" : record->key);
411 GNUNET_SERVER_notification_context_add (nc, client);
412 record->client = client; 438 record->client = client;
413 if (GNUNET_OK != 439 if (GNUNET_OK !=
414 db->iterate_records (db->cls, record->sub_system, record->peer, 440 db->iterate_records (db->cls,
415 record->key, &record_iterator, record)) 441 record->sub_system,
442 record->peer,
443 record->key,
444 &record_iterator,
445 record))
416 { 446 {
417 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 447 GNUNET_SERVICE_client_drop (client);
418 PEERSTORE_destroy_record (record); 448 PEERSTORE_destroy_record (record);
419 } 449 }
420} 450}
@@ -427,186 +457,174 @@ handle_iterate (void *cls, struct GNUNET_SERVER_Client *client,
427 * @param success result 457 * @param success result
428 */ 458 */
429static void 459static void
430store_record_continuation (void *cls, int success) 460store_record_continuation (void *cls,
461 int success)
431{ 462{
432 struct GNUNET_PEERSTORE_Record *record = cls; 463 struct GNUNET_PEERSTORE_Record *record = cls;
433 464
434 GNUNET_SERVER_receive_done (record->client, success);
435 if (GNUNET_OK == success) 465 if (GNUNET_OK == success)
436 { 466 {
437 watch_notifier (record); 467 watch_notifier (record);
468 GNUNET_SERVICE_client_continue (record->client);
469 }
470 else
471 {
472 GNUNET_SERVICE_client_drop (record->client);
438 } 473 }
439 PEERSTORE_destroy_record (record); 474 PEERSTORE_destroy_record (record);
440} 475}
441 476
442 477
443/** 478/**
444 * Handle a store request from client 479 * Check a store request from client
445 * 480 *
446 * @param cls unused 481 * @param cls client identification of the client
447 * @param client identification of the client 482 * @param srm the actual message
448 * @param message the actual message 483 * @return #GNUNET_OK if @a srm is well-formed
449 */ 484 */
450static void 485static int
451handle_store (void *cls, struct GNUNET_SERVER_Client *client, 486check_store (void *cls,
452 const struct GNUNET_MessageHeader *message) 487 const struct StoreRecordMessage *srm)
453{ 488{
454 struct GNUNET_PEERSTORE_Record *record; 489 struct GNUNET_PEERSTORE_Record *record;
455 struct StoreRecordMessage *srm;
456 490
457 record = PEERSTORE_parse_record_message (message); 491 record = PEERSTORE_parse_record_message (srm);
458 if (NULL == record) 492 if (NULL == record)
459 { 493 {
460 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 494 GNUNET_break (0);
461 _("Malformed store request from client\n")); 495 return GNUNET_SYSERR;
462 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
463 return;
464 } 496 }
465 srm = (struct StoreRecordMessage *) message; 497 if ( (NULL == record->sub_system) ||
466 if (NULL == record->sub_system || NULL == record->peer || NULL == record->key) 498 (NULL == record->peer) ||
499 (NULL == record->key) )
467 { 500 {
468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 501 GNUNET_break (0);
469 _("Full key not supplied in client store request\n"));
470 PEERSTORE_destroy_record (record); 502 PEERSTORE_destroy_record (record);
471 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 503 return GNUNET_SYSERR;
472 return;
473 } 504 }
505 PEERSTORE_destroy_record (record);
506 return GNUNET_OK;
507}
508
509
510/**
511 * Handle a store request from client
512 *
513 * @param cls client identification of the client
514 * @param srm the actual message
515 */
516static void
517handle_store (void *cls,
518 const struct StoreRecordMessage *srm)
519{
520 struct GNUNET_SERVICE_Client *client = cls;
521 struct GNUNET_PEERSTORE_Record *record;
522
523 record = PEERSTORE_parse_record_message (srm);
474 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 524 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
475 "Received a store request (size: %u). Sub system `%s' Peer `%s Key `%s' Options: %d.\n", 525 "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %d.\n",
476 (unsigned int) record->value_size,
477 record->sub_system, 526 record->sub_system,
478 GNUNET_i2s (record->peer), 527 GNUNET_i2s (record->peer),
479 record->key, 528 record->key,
480 ntohl (srm->options)); 529 ntohl (srm->options));
481 record->client = client; 530 record->client = client;
482 if (GNUNET_OK != 531 if (GNUNET_OK !=
483 db->store_record (db->cls, record->sub_system, record->peer, record->key, 532 db->store_record (db->cls,
484 record->value, record->value_size, *record->expiry, 533 record->sub_system,
485 ntohl (srm->options), store_record_continuation, 534 record->peer,
535 record->key,
536 record->value,
537 record->value_size,
538 *record->expiry,
539 ntohl (srm->options),
540 &store_record_continuation,
486 record)) 541 record))
487 { 542 {
488 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
489 _("Failed to store requested value, database error."));
490 PEERSTORE_destroy_record (record); 543 PEERSTORE_destroy_record (record);
491 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 544 GNUNET_SERVICE_client_drop (client);
492 return; 545 return;
493 } 546 }
494} 547}
495 548
496 549
497/** 550/**
498 * Creates an entry for a new client or returns it if it already exists.
499 *
500 * @param client Client handle
501 * @return Client entry struct
502 */
503static struct ClientEntry *
504make_client_entry (struct GNUNET_SERVER_Client *client)
505{
506 struct ClientEntry *ce;
507
508 ce = client_head;
509 while (NULL != ce)
510 {
511 if (ce->client == client)
512 return ce;
513 ce = ce->next;
514 }
515 if (GNUNET_YES == in_shutdown)
516 {
517 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
518 return NULL;
519 }
520 ce = GNUNET_new (struct ClientEntry);
521 ce->client = client;
522 GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ce);
523 return ce;
524}
525
526
527/**
528 * Callback on a new client connection
529 *
530 * @param cls closure (unused)
531 * @param client identification of the client
532 */
533static void
534handle_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
535{
536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New client connection created.\n");
537 make_client_entry (client);
538}
539
540
541/**
542 * Peerstore service runner. 551 * Peerstore service runner.
543 * 552 *
544 * @param cls closure 553 * @param cls closure
545 * @param server the initialized server
546 * @param c configuration to use 554 * @param c configuration to use
555 * @param service the initialized service
547 */ 556 */
548static void 557static void
549run (void *cls, struct GNUNET_SERVER_Handle *server, 558run (void *cls,
550 const struct GNUNET_CONFIGURATION_Handle *c) 559 const struct GNUNET_CONFIGURATION_Handle *c,
560 struct GNUNET_SERVICE_Handle *service)
551{ 561{
552 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
553 {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0},
554 {&handle_iterate, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE, 0},
555 {&handle_watch, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH,
556 sizeof (struct StoreKeyHashMessage)},
557 {&handle_watch_cancel, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL,
558 sizeof (struct StoreKeyHashMessage)},
559 {NULL, NULL, 0, 0}
560 };
561 char *database; 562 char *database;
562 563
563 in_shutdown = GNUNET_NO; 564 in_shutdown = GNUNET_NO;
564 cfg = c; 565 cfg = c;
565 if (GNUNET_OK != 566 if (GNUNET_OK !=
566 GNUNET_CONFIGURATION_get_value_string (cfg, "peerstore", "DATABASE", 567 GNUNET_CONFIGURATION_get_value_string (cfg,
568 "peerstore",
569 "DATABASE",
567 &database)) 570 &database))
568 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("No database backend configured\n"));
569
570 else
571 { 571 {
572 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_peerstore_%s", database); 572 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
573 db = GNUNET_PLUGIN_load (db_lib_name, (void *) cfg); 573 "peerstore",
574 GNUNET_free (database); 574 "DATABASE");
575 GNUNET_SCHEDULER_shutdown ();
576 return;
575 } 577 }
578 GNUNET_asprintf (&db_lib_name,
579 "libgnunet_plugin_peerstore_%s",
580 database);
581 db = GNUNET_PLUGIN_load (db_lib_name,
582 (void *) cfg);
583 GNUNET_free (database);
576 if (NULL == db) 584 if (NULL == db)
577 { 585 {
578 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 586 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
579 _("Could not load database backend `%s'\n"), 587 _("Could not load database backend `%s'\n"),
580 db_lib_name); 588 db_lib_name);
581 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); 589 GNUNET_SCHEDULER_shutdown ();
582 return; 590 return;
583 } 591 }
584 nc = GNUNET_SERVER_notification_context_create (server, 16); 592 watchers = GNUNET_CONTAINER_multihashmap_create (10,
585 watchers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 593 GNUNET_NO);
586 expire_task = GNUNET_SCHEDULER_add_now (&cleanup_expired_records, 594 expire_task = GNUNET_SCHEDULER_add_now (&cleanup_expired_records,
587 NULL); 595 NULL);
588 GNUNET_SERVER_add_handlers (server, handlers);
589 GNUNET_SERVER_connect_notify (server, &handle_client_connect, NULL);
590 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
591 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 596 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
592 NULL); 597 NULL);
593} 598}
594 599
595 600
596/** 601/**
597 * The main function for the peerstore service. 602 * Define "main" method using service macro.
598 *
599 * @param argc number of arguments from the command line
600 * @param argv command line arguments
601 * @return 0 ok, 1 on error
602 */ 603 */
603int 604GNUNET_SERVICE_MAIN
604main (int argc, char *const *argv) 605("peerstore",
605{ 606 GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN,
606 return (GNUNET_OK == 607 &run,
607 GNUNET_SERVICE_run (argc, argv, "peerstore", 608 &client_connect_cb,
608 GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, &run, 609 &client_disconnect_cb,
609 NULL)) ? 0 : 1; 610 NULL,
610} 611 GNUNET_MQ_hd_var_size (store,
612 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE,
613 struct StoreRecordMessage,
614 NULL),
615 GNUNET_MQ_hd_var_size (iterate,
616 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE,
617 struct StoreRecordMessage,
618 NULL),
619 GNUNET_MQ_hd_fixed_size (watch,
620 GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH,
621 struct StoreKeyHashMessage,
622 NULL),
623 GNUNET_MQ_hd_fixed_size (watch_cancel,
624 GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL,
625 struct StoreKeyHashMessage,
626 NULL),
627 GNUNET_MQ_handler_end ());
628
611 629
612/* end of gnunet-service-peerstore.c */ 630/* end of gnunet-service-peerstore.c */
diff --git a/src/peerstore/peerstore.h b/src/peerstore/peerstore.h
index f5e2cd19c..8b3c4dd92 100644
--- a/src/peerstore/peerstore.h
+++ b/src/peerstore/peerstore.h
@@ -33,7 +33,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
33/** 33/**
34 * Message carrying a PEERSTORE record message 34 * Message carrying a PEERSTORE record message
35 */ 35 */
36 struct StoreRecordMessage 36struct StoreRecordMessage
37{ 37{
38 38
39 /** 39 /**
@@ -78,8 +78,9 @@ GNUNET_NETWORK_STRUCT_BEGIN
78 * Options, needed only in case of a 78 * Options, needed only in case of a
79 * store operation 79 * store operation
80 */ 80 */
81 uint32_t /* enum GNUNET_PEERSTORE_StoreOption */ options 81 uint32_t /* enum GNUNET_PEERSTORE_StoreOption */ options GNUNET_PACKED;
82 GNUNET_PACKED; 82
83 /* Followed by key and value */
83 84
84}; 85};
85 86
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index f6910c017..47bf7775e 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -579,7 +579,7 @@ handle_iterate_end (void *cls,
579 */ 579 */
580static int 580static int
581check_iterate_result (void *cls, 581check_iterate_result (void *cls,
582 const struct GNUNET_MessageHeader *msg) 582 const struct StoreRecordMessage *msg)
583{ 583{
584 /* we defer validation to #handle_iterate_result */ 584 /* we defer validation to #handle_iterate_result */
585 return GNUNET_OK; 585 return GNUNET_OK;
@@ -594,7 +594,7 @@ check_iterate_result (void *cls,
594 */ 594 */
595static void 595static void
596handle_iterate_result (void *cls, 596handle_iterate_result (void *cls,
597 const struct GNUNET_MessageHeader *msg) 597 const struct StoreRecordMessage *msg)
598{ 598{
599 struct GNUNET_PEERSTORE_Handle *h = cls; 599 struct GNUNET_PEERSTORE_Handle *h = cls;
600 struct GNUNET_PEERSTORE_IterateContext *ic; 600 struct GNUNET_PEERSTORE_IterateContext *ic;
@@ -725,7 +725,7 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
725 */ 725 */
726static int 726static int
727check_watch_record (void *cls, 727check_watch_record (void *cls,
728 const struct GNUNET_MessageHeader *msg) 728 const struct StoreRecordMessage *msg)
729{ 729{
730 /* we defer validation to #handle_watch_result */ 730 /* we defer validation to #handle_watch_result */
731 return GNUNET_OK; 731 return GNUNET_OK;
@@ -740,7 +740,7 @@ check_watch_record (void *cls,
740 */ 740 */
741static void 741static void
742handle_watch_record (void *cls, 742handle_watch_record (void *cls,
743 const struct GNUNET_MessageHeader *msg) 743 const struct StoreRecordMessage *msg)
744{ 744{
745 struct GNUNET_PEERSTORE_Handle *h = cls; 745 struct GNUNET_PEERSTORE_Handle *h = cls;
746 struct GNUNET_PEERSTORE_Record *record; 746 struct GNUNET_PEERSTORE_Record *record;
@@ -793,11 +793,11 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
793 h), 793 h),
794 GNUNET_MQ_hd_var_size (iterate_result, 794 GNUNET_MQ_hd_var_size (iterate_result,
795 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_RECORD, 795 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_RECORD,
796 struct GNUNET_MessageHeader, 796 struct StoreRecordMessage,
797 h), 797 h),
798 GNUNET_MQ_hd_var_size (watch_record, 798 GNUNET_MQ_hd_var_size (watch_record,
799 GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_RECORD, 799 GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_RECORD,
800 struct GNUNET_MessageHeader, 800 struct StoreRecordMessage,
801 h), 801 h),
802 GNUNET_MQ_handler_end () 802 GNUNET_MQ_handler_end ()
803 }; 803 };
@@ -936,18 +936,20 @@ GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h,
936 wc->h = h; 936 wc->h = h;
937 wc->keyhash = hm->keyhash; 937 wc->keyhash = hm->keyhash;
938 if (NULL == h->watches) 938 if (NULL == h->watches)
939 h->watches = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO); 939 h->watches = GNUNET_CONTAINER_multihashmap_create (5,
940 GNUNET_NO);
940 GNUNET_assert (GNUNET_OK == 941 GNUNET_assert (GNUNET_OK ==
941 GNUNET_CONTAINER_multihashmap_put (h->watches, 942 GNUNET_CONTAINER_multihashmap_put (h->watches,
942 &wc->keyhash, 943 &wc->keyhash,
943 wc, 944 wc,
944 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 945 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
945 LOG (GNUNET_ERROR_TYPE_DEBUG, 946 LOG (GNUNET_ERROR_TYPE_DEBUG,
946 "Sending a watch request for ss `%s', peer `%s', key `%s'.\n", 947 "Sending a watch request for subsystem `%s', peer `%s', key `%s'.\n",
947 sub_system, 948 sub_system,
948 GNUNET_i2s (peer), 949 GNUNET_i2s (peer),
949 key); 950 key);
950 GNUNET_MQ_send (h->mq, ev); 951 GNUNET_MQ_send (h->mq,
952 ev);
951 return wc; 953 return wc;
952} 954}
953 955
diff --git a/src/peerstore/peerstore_common.c b/src/peerstore/peerstore_common.c
index 07d43db2e..d12c4e21e 100644
--- a/src/peerstore/peerstore_common.c
+++ b/src/peerstore/peerstore_common.c
@@ -31,7 +31,8 @@
31 */ 31 */
32void 32void
33PEERSTORE_hash_key (const char *sub_system, 33PEERSTORE_hash_key (const char *sub_system,
34 const struct GNUNET_PeerIdentity *peer, const char *key, 34 const struct GNUNET_PeerIdentity *peer,
35 const char *key,
35 struct GNUNET_HashCode *ret) 36 struct GNUNET_HashCode *ret)
36{ 37{
37 size_t sssize; 38 size_t sssize;
@@ -58,64 +59,6 @@ PEERSTORE_hash_key (const char *sub_system,
58 59
59 60
60/** 61/**
61 * Creates a record message ready to be sent
62 *
63 * @param sub_system sub system string
64 * @param peer Peer identity (can be NULL)
65 * @param key record key string (can be NULL)
66 * @param value record value BLOB (can be NULL)
67 * @param value_size record value size in bytes (set to 0 if value is NULL)
68 * @param expiry absolute time after which the record expires
69 * @param msg_type message type to be set in header
70 * @return pointer to record message struct
71 */
72struct StoreRecordMessage *
73PEERSTORE_create_record_message (const char *sub_system,
74 const struct GNUNET_PeerIdentity *peer,
75 const char *key, const void *value,
76 size_t value_size,
77 struct GNUNET_TIME_Absolute *expiry,
78 uint16_t msg_type)
79{
80 struct StoreRecordMessage *srm;
81 size_t ss_size;
82 size_t key_size;
83 size_t request_size;
84 void *dummy;
85
86 ss_size = strlen (sub_system) + 1;
87 if (NULL == key)
88 key_size = 0;
89 else
90 key_size = strlen (key) + 1;
91 request_size =
92 sizeof (struct StoreRecordMessage) + ss_size + key_size + value_size;
93 srm = GNUNET_malloc (request_size);
94 srm->header.size = htons (request_size);
95 srm->header.type = htons (msg_type);
96 srm->key_size = htons (key_size);
97 if (NULL != expiry)
98 srm->expiry = *expiry;
99 if (NULL == peer)
100 srm->peer_set = htons (GNUNET_NO);
101 else
102 {
103 srm->peer_set = htons (GNUNET_YES);
104 srm->peer = *peer;
105 }
106 srm->sub_system_size = htons (ss_size);
107 srm->value_size = htons (value_size);
108 dummy = &srm[1];
109 GNUNET_memcpy (dummy, sub_system, ss_size);
110 dummy += ss_size;
111 GNUNET_memcpy (dummy, key, key_size);
112 dummy += key_size;
113 GNUNET_memcpy (dummy, value, value_size);
114 return srm;
115}
116
117
118/**
119 * Creates a MQ envelope for a single record 62 * Creates a MQ envelope for a single record
120 * 63 *
121 * @param sub_system sub system string 64 * @param sub_system sub system string
@@ -131,7 +74,8 @@ PEERSTORE_create_record_message (const char *sub_system,
131struct GNUNET_MQ_Envelope * 74struct GNUNET_MQ_Envelope *
132PEERSTORE_create_record_mq_envelope (const char *sub_system, 75PEERSTORE_create_record_mq_envelope (const char *sub_system,
133 const struct GNUNET_PeerIdentity *peer, 76 const struct GNUNET_PeerIdentity *peer,
134 const char *key, const void *value, 77 const char *key,
78 const void *value,
135 size_t value_size, 79 size_t value_size,
136 struct GNUNET_TIME_Absolute *expiry, 80 struct GNUNET_TIME_Absolute *expiry,
137 enum GNUNET_PEERSTORE_StoreOption options, 81 enum GNUNET_PEERSTORE_StoreOption options,
@@ -178,13 +122,12 @@ PEERSTORE_create_record_mq_envelope (const char *sub_system,
178/** 122/**
179 * Parses a message carrying a record 123 * Parses a message carrying a record
180 * 124 *
181 * @param message the actual message 125 * @param srm the actual message
182 * @return Pointer to record or NULL if error 126 * @return Pointer to record or NULL if error
183 */ 127 */
184struct GNUNET_PEERSTORE_Record * 128struct GNUNET_PEERSTORE_Record *
185PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message) 129PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm)
186{ 130{
187 struct StoreRecordMessage *srm;
188 struct GNUNET_PEERSTORE_Record *record; 131 struct GNUNET_PEERSTORE_Record *record;
189 uint16_t req_size; 132 uint16_t req_size;
190 uint16_t ss_size; 133 uint16_t ss_size;
@@ -192,37 +135,20 @@ PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message)
192 uint16_t value_size; 135 uint16_t value_size;
193 char *dummy; 136 char *dummy;
194 137
195 req_size = ntohs (message->size); 138 req_size = ntohs (srm->header.size) - sizeof (*srm);
196 if (req_size < sizeof (struct StoreRecordMessage))
197 {
198 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
199 "Received message with invalid size: (%d < %d).\n",
200 (int) req_size,
201 (int) sizeof (struct StoreRecordMessage));
202 return NULL;
203 }
204 srm = (struct StoreRecordMessage *) message;
205 ss_size = ntohs (srm->sub_system_size); 139 ss_size = ntohs (srm->sub_system_size);
206 key_size = ntohs (srm->key_size); 140 key_size = ntohs (srm->key_size);
207 value_size = ntohs (srm->value_size); 141 value_size = ntohs (srm->value_size);
208 if (ss_size + key_size + value_size + sizeof (struct StoreRecordMessage) != 142 if (ss_size + key_size + value_size != req_size)
209 req_size)
210 { 143 {
211 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 144 GNUNET_break (0);
212 "Received message with invalid sizes: (%d + %d + %d + %d != %d).\n",
213 ss_size,
214 key_size,
215 value_size,
216 (int) sizeof (struct StoreRecordMessage),
217 req_size);
218 return NULL; 145 return NULL;
219 } 146 }
220 record = GNUNET_new (struct GNUNET_PEERSTORE_Record); 147 record = GNUNET_new (struct GNUNET_PEERSTORE_Record);
221 if (GNUNET_YES == ntohs (srm->peer_set)) 148 if (GNUNET_YES == ntohs (srm->peer_set))
222 { 149 {
223 record->peer = GNUNET_new (struct GNUNET_PeerIdentity); 150 record->peer = GNUNET_new (struct GNUNET_PeerIdentity);
224 151 *record->peer = srm->peer;
225 GNUNET_memcpy (record->peer, &srm->peer, sizeof (struct GNUNET_PeerIdentity));
226 } 152 }
227 record->expiry = GNUNET_new (struct GNUNET_TIME_Absolute); 153 record->expiry = GNUNET_new (struct GNUNET_TIME_Absolute);
228 154
diff --git a/src/peerstore/peerstore_common.h b/src/peerstore/peerstore_common.h
index 4b806bf91..3d938b5da 100644
--- a/src/peerstore/peerstore_common.h
+++ b/src/peerstore/peerstore_common.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 3 Copyright (C) 2013-2016 GNUnet e.V.
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
@@ -23,7 +23,6 @@
23 * @brief Helper peerstore functions 23 * @brief Helper peerstore functions
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 */ 25 */
26
27#include "platform.h" 26#include "platform.h"
28#include "peerstore.h" 27#include "peerstore.h"
29 28
@@ -33,28 +32,10 @@
33 */ 32 */
34void 33void
35PEERSTORE_hash_key (const char *sub_system, 34PEERSTORE_hash_key (const char *sub_system,
36 const struct GNUNET_PeerIdentity *peer, const char *key, 35 const struct GNUNET_PeerIdentity *peer,
36 const char *key,
37 struct GNUNET_HashCode *ret); 37 struct GNUNET_HashCode *ret);
38 38
39/**
40 * Creates a record message ready to be sent
41 *
42 * @param sub_system sub system string
43 * @param peer Peer identity (can be NULL)
44 * @param key record key string (can be NULL)
45 * @param value record value BLOB (can be NULL)
46 * @param value_size record value size in bytes (set to 0 if value is NULL)
47 * @param expiry absolute time after which the record expires
48 * @param msg_type message type to be set in header
49 * @return pointer to record message struct
50 */
51struct StoreRecordMessage *
52PEERSTORE_create_record_message (const char *sub_system,
53 const struct GNUNET_PeerIdentity *peer,
54 const char *key, const void *value,
55 size_t value_size,
56 struct GNUNET_TIME_Absolute *expiry,
57 uint16_t msg_type);
58 39
59/** 40/**
60 * Creates a MQ envelope for a single record 41 * Creates a MQ envelope for a single record
@@ -72,20 +53,23 @@ PEERSTORE_create_record_message (const char *sub_system,
72struct GNUNET_MQ_Envelope * 53struct GNUNET_MQ_Envelope *
73PEERSTORE_create_record_mq_envelope (const char *sub_system, 54PEERSTORE_create_record_mq_envelope (const char *sub_system,
74 const struct GNUNET_PeerIdentity *peer, 55 const struct GNUNET_PeerIdentity *peer,
75 const char *key, const void *value, 56 const char *key,
57 const void *value,
76 size_t value_size, 58 size_t value_size,
77 struct GNUNET_TIME_Absolute *expiry, 59 struct GNUNET_TIME_Absolute *expiry,
78 enum GNUNET_PEERSTORE_StoreOption options, 60 enum GNUNET_PEERSTORE_StoreOption options,
79 uint16_t msg_type); 61 uint16_t msg_type);
80 62
63
81/** 64/**
82 * Parses a message carrying a record 65 * Parses a message carrying a record
83 * 66 *
84 * @param message the actual message 67 * @param srm the actual message
85 * @return Pointer to record or NULL if error 68 * @return Pointer to record or NULL on error
86 */ 69 */
87struct GNUNET_PEERSTORE_Record * 70struct GNUNET_PEERSTORE_Record *
88PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message); 71PEERSTORE_parse_record_message (const struct StoreRecordMessage *srm);
72
89 73
90/** 74/**
91 * Free any memory allocated for this record 75 * Free any memory allocated for this record
@@ -94,3 +78,5 @@ PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message);
94 */ 78 */
95void 79void
96PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record); 80PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record);
81
82/* end of peerstore_common.h */
diff --git a/src/peerstore/test_peerstore_api_watch.c b/src/peerstore/test_peerstore_api_watch.c
index 91902ba9e..1c9995c31 100644
--- a/src/peerstore/test_peerstore_api_watch.c
+++ b/src/peerstore/test_peerstore_api_watch.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C) 2013-2016 GNUnet e.V.
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
@@ -26,47 +26,74 @@
26#include "gnunet_testing_lib.h" 26#include "gnunet_testing_lib.h"
27#include "gnunet_peerstore_service.h" 27#include "gnunet_peerstore_service.h"
28 28
29
29static int ok = 1; 30static int ok = 1;
30 31
31static struct GNUNET_PEERSTORE_Handle *h; 32static struct GNUNET_PEERSTORE_Handle *h;
32 33
33static char *ss = "test_peerstore_api_watch"; 34static char *ss = "test_peerstore_api_watch";
34static struct GNUNET_PeerIdentity p; 35
35static char *k = "test_peerstore_api_watch_key"; 36static char *k = "test_peerstore_api_watch_key";
37
36static char *val = "test_peerstore_api_watch_val"; 38static char *val = "test_peerstore_api_watch_val";
37 39
40
38static void 41static void
39watch_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, 42watch_cb (void *cls,
43 const struct GNUNET_PEERSTORE_Record *record,
40 const char *emsg) 44 const char *emsg)
41{ 45{
42 GNUNET_assert (NULL == emsg); 46 GNUNET_assert (NULL == emsg);
43 GNUNET_assert (0 == strcmp (val, (char *) record->value)); 47 GNUNET_assert (0 == strcmp (val,
48 (char *) record->value));
44 ok = 0; 49 ok = 0;
45 GNUNET_PEERSTORE_disconnect (h, GNUNET_NO); 50 GNUNET_PEERSTORE_disconnect (h,
51 GNUNET_NO);
46 GNUNET_SCHEDULER_shutdown (); 52 GNUNET_SCHEDULER_shutdown ();
47} 53}
48 54
49 55
50static void 56static void
51run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, 57run (void *cls,
58 const struct GNUNET_CONFIGURATION_Handle *cfg,
52 struct GNUNET_TESTING_Peer *peer) 59 struct GNUNET_TESTING_Peer *peer)
53{ 60{
61 struct GNUNET_PeerIdentity p;
62
54 h = GNUNET_PEERSTORE_connect (cfg); 63 h = GNUNET_PEERSTORE_connect (cfg);
55 GNUNET_assert (NULL != h); 64 GNUNET_assert (NULL != h);
56 memset (&p, 4, sizeof (p)); 65 memset (&p,
57 GNUNET_PEERSTORE_watch (h, ss, &p, k, &watch_cb, NULL); 66 4,
58 GNUNET_PEERSTORE_store (h, ss, &p, k, val, strlen (val) + 1, 67 sizeof (p));
68 GNUNET_PEERSTORE_watch (h,
69 ss,
70 &p,
71 k,
72 &watch_cb,
73 NULL);
74 GNUNET_PEERSTORE_store (h,
75 ss,
76 &p,
77 k,
78 val,
79 strlen (val) + 1,
59 GNUNET_TIME_UNIT_FOREVER_ABS, 80 GNUNET_TIME_UNIT_FOREVER_ABS,
60 GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); 81 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
82 NULL,
83 NULL);
61} 84}
62 85
63 86
64int 87int
65main (int argc, char *argv[]) 88main (int argc,
89 char *argv[])
66{ 90{
67 if (0 != 91 if (0 !=
68 GNUNET_TESTING_service_run ("test-gnunet-peerstore", "peerstore", 92 GNUNET_TESTING_service_run ("test-gnunet-peerstore",
69 "test_peerstore_api_data.conf", &run, NULL)) 93 "peerstore",
94 "test_peerstore_api_data.conf",
95 &run,
96 NULL))
70 return 1; 97 return 1;
71 return ok; 98 return ok;
72} 99}