diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-05-30 16:06:00 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-05-30 16:06:00 +0000 |
commit | 95cdeb5c0bb1f14f3959863e6bf4675db48ea177 (patch) | |
tree | 545e2a910c0efdae9dc2e2af8da45efa007cdf32 /src/peerstore | |
parent | 02f9d1e7389d0da0a475ae0035b67801c7ca2d06 (diff) | |
download | gnunet-95cdeb5c0bb1f14f3959863e6bf4675db48ea177.tar.gz gnunet-95cdeb5c0bb1f14f3959863e6bf4675db48ea177.zip |
peerstore: towards watch functionality
Diffstat (limited to 'src/peerstore')
-rw-r--r-- | src/peerstore/gnunet-service-peerstore.c | 79 | ||||
-rw-r--r-- | src/peerstore/peerstore.h | 18 | ||||
-rw-r--r-- | src/peerstore/peerstore_api.c | 142 | ||||
-rw-r--r-- | src/peerstore/peerstore_common.c | 32 | ||||
-rw-r--r-- | src/peerstore/peerstore_common.h | 10 | ||||
-rw-r--r-- | src/peerstore/test_peerstore_api.c | 38 |
6 files changed, 275 insertions, 44 deletions
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c index c410630c9..70d79ea5e 100644 --- a/src/peerstore/gnunet-service-peerstore.c +++ b/src/peerstore/gnunet-service-peerstore.c | |||
@@ -29,7 +29,23 @@ | |||
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 | //TODO: GNUNET_SERVER_receive_done() ? | 32 | /** |
33 | * Context of a PEERSTORE watch | ||
34 | */ | ||
35 | struct WatchContext | ||
36 | { | ||
37 | |||
38 | /** | ||
39 | * Hash of key of watched record | ||
40 | */ | ||
41 | struct GNUNET_HashCode keyhash; | ||
42 | |||
43 | /** | ||
44 | * Client requested the watch | ||
45 | */ | ||
46 | struct GNUNET_SERVER_Client *client; | ||
47 | |||
48 | }; | ||
33 | 49 | ||
34 | /** | 50 | /** |
35 | * Interval for expired records cleanup (in seconds) | 51 | * Interval for expired records cleanup (in seconds) |
@@ -52,6 +68,11 @@ char *db_lib_name; | |||
52 | static struct GNUNET_PEERSTORE_PluginFunctions *db; | 68 | static struct GNUNET_PEERSTORE_PluginFunctions *db; |
53 | 69 | ||
54 | /** | 70 | /** |
71 | * Hashmap with all watch requests | ||
72 | */ | ||
73 | static struct GNUNET_CONTAINER_MultiHashMap *watchers; | ||
74 | |||
75 | /** | ||
55 | * Task run during shutdown. | 76 | * Task run during shutdown. |
56 | * | 77 | * |
57 | * @param cls unused | 78 | * @param cls unused |
@@ -67,7 +88,8 @@ shutdown_task (void *cls, | |||
67 | GNUNET_free (db_lib_name); | 88 | GNUNET_free (db_lib_name); |
68 | db_lib_name = NULL; | 89 | db_lib_name = NULL; |
69 | } | 90 | } |
70 | 91 | if(NULL != watchers) | |
92 | GNUNET_CONTAINER_multihashmap_destroy(watchers); | ||
71 | GNUNET_SCHEDULER_shutdown(); | 93 | GNUNET_SCHEDULER_shutdown(); |
72 | } | 94 | } |
73 | 95 | ||
@@ -132,6 +154,55 @@ int record_iterator(void *cls, | |||
132 | } | 154 | } |
133 | 155 | ||
134 | /** | 156 | /** |
157 | * Handle a watch cancel request from client | ||
158 | * | ||
159 | * @param cls unused | ||
160 | * @param client identification of the client | ||
161 | * @param message the actual message | ||
162 | */ | ||
163 | void handle_watch_cancel (void *cls, | ||
164 | struct GNUNET_SERVER_Client *client, | ||
165 | const struct GNUNET_MessageHeader *message) | ||
166 | { | ||
167 | struct StoreKeyHashMessage *hm; | ||
168 | |||
169 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a watch cancel request from client.\n"); | ||
170 | if(NULL == watchers) | ||
171 | { | ||
172 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
173 | "Received a watch cancel request when we don't have any watchers.\n"); | ||
174 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | ||
175 | return; | ||
176 | } | ||
177 | hm = (struct StoreKeyHashMessage *) message; | ||
178 | GNUNET_CONTAINER_multihashmap_remove(watchers, &hm->keyhash, client); | ||
179 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * Handle a watch request from client | ||
184 | * | ||
185 | * @param cls unused | ||
186 | * @param client identification of the client | ||
187 | * @param message the actual message | ||
188 | */ | ||
189 | void handle_watch (void *cls, | ||
190 | struct GNUNET_SERVER_Client *client, | ||
191 | const struct GNUNET_MessageHeader *message) | ||
192 | { | ||
193 | struct StoreKeyHashMessage *hm; | ||
194 | |||
195 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a watch request from client.\n"); | ||
196 | hm = (struct StoreKeyHashMessage *) message; | ||
197 | GNUNET_SERVER_client_mark_monitor(client); | ||
198 | if(NULL == watchers) | ||
199 | watchers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | ||
200 | GNUNET_CONTAINER_multihashmap_put(watchers, &hm->keyhash, | ||
201 | client, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
202 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | ||
203 | } | ||
204 | |||
205 | /** | ||
135 | * Handle an iterate request from client | 206 | * Handle an iterate request from client |
136 | * | 207 | * |
137 | * @param cls unused | 208 | * @param cls unused |
@@ -232,7 +303,7 @@ void handle_store (void *cls, | |||
232 | tc = GNUNET_SERVER_transmit_context_create (client); | 303 | tc = GNUNET_SERVER_transmit_context_create (client); |
233 | GNUNET_SERVER_transmit_context_append_data(tc, NULL, 0, response_type); | 304 | GNUNET_SERVER_transmit_context_append_data(tc, NULL, 0, response_type); |
234 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | 305 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); |
235 | 306 | //TODO: notify watchers, if a client is disconnected, remove its watch entry | |
236 | } | 307 | } |
237 | 308 | ||
238 | /** | 309 | /** |
@@ -250,6 +321,8 @@ run (void *cls, | |||
250 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 321 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
251 | {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0}, | 322 | {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0}, |
252 | {&handle_iterate, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE, 0}, | 323 | {&handle_iterate, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE, 0}, |
324 | {&handle_watch, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH, sizeof(struct StoreKeyHashMessage)}, | ||
325 | {&handle_watch_cancel, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL, sizeof(struct StoreKeyHashMessage)}, | ||
253 | {NULL, NULL, 0, 0} | 326 | {NULL, NULL, 0, 0} |
254 | }; | 327 | }; |
255 | char *database; | 328 | char *database; |
diff --git a/src/peerstore/peerstore.h b/src/peerstore/peerstore.h index 7c6e6bdbc..5adf9f363 100644 --- a/src/peerstore/peerstore.h +++ b/src/peerstore/peerstore.h | |||
@@ -77,6 +77,24 @@ struct StoreRecordMessage | |||
77 | 77 | ||
78 | }; | 78 | }; |
79 | 79 | ||
80 | /** | ||
81 | * Message carrying record key hash | ||
82 | */ | ||
83 | struct StoreKeyHashMessage | ||
84 | { | ||
85 | |||
86 | /** | ||
87 | * GNUnet message header | ||
88 | */ | ||
89 | struct GNUNET_MessageHeader header; | ||
90 | |||
91 | /** | ||
92 | * Hash of a record key | ||
93 | */ | ||
94 | struct GNUNET_HashCode keyhash; | ||
95 | |||
96 | }; | ||
97 | |||
80 | GNUNET_NETWORK_STRUCT_END | 98 | GNUNET_NETWORK_STRUCT_END |
81 | 99 | ||
82 | #endif | 100 | #endif |
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c index 14b1c3e88..c9a68f4bf 100644 --- a/src/peerstore/peerstore_api.c +++ b/src/peerstore/peerstore_api.c | |||
@@ -76,14 +76,9 @@ struct GNUNET_PEERSTORE_Handle | |||
76 | struct GNUNET_PEERSTORE_IterateContext *iterate_tail; | 76 | struct GNUNET_PEERSTORE_IterateContext *iterate_tail; |
77 | 77 | ||
78 | /** | 78 | /** |
79 | * Head of WATCH requests (active and inactive). | 79 | * Hashmap of watch requests |
80 | */ | 80 | */ |
81 | struct GNUNET_PEERSTORE_WatchContext *watch_head; | 81 | struct GNUNET_CONTAINER_MultiHashMap *watches; |
82 | |||
83 | /** | ||
84 | * Tail of WATCH requests (active and inactive). | ||
85 | */ | ||
86 | struct GNUNET_PEERSTORE_WatchContext *watch_tail; | ||
87 | 82 | ||
88 | }; | 83 | }; |
89 | 84 | ||
@@ -215,6 +210,11 @@ struct GNUNET_PEERSTORE_WatchContext | |||
215 | void *callback_cls; | 210 | void *callback_cls; |
216 | 211 | ||
217 | /** | 212 | /** |
213 | * Hash of the combined key | ||
214 | */ | ||
215 | struct GNUNET_HashCode keyhash; | ||
216 | |||
217 | /** | ||
218 | * #GNUNET_YES / #GNUNET_NO | 218 | * #GNUNET_YES / #GNUNET_NO |
219 | * if sent, cannot be canceled | 219 | * if sent, cannot be canceled |
220 | */ | 220 | */ |
@@ -284,27 +284,6 @@ handle_client_error (void *cls, enum GNUNET_MQ_Error error) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | /** | 286 | /** |
287 | * Should be called only after destroying MQ and connection | ||
288 | */ | ||
289 | static void | ||
290 | cleanup_handle(struct GNUNET_PEERSTORE_Handle *h) | ||
291 | { | ||
292 | struct GNUNET_PEERSTORE_StoreContext *sc; | ||
293 | struct GNUNET_PEERSTORE_IterateContext *ic; | ||
294 | |||
295 | while (NULL != (sc = h->store_head)) | ||
296 | { | ||
297 | GNUNET_CONTAINER_DLL_remove(h->store_head, h->store_tail, sc); | ||
298 | GNUNET_free(sc); | ||
299 | } | ||
300 | while (NULL != (ic = h->iterate_head)) | ||
301 | { | ||
302 | GNUNET_CONTAINER_DLL_remove(h->iterate_head, h->iterate_tail, ic); | ||
303 | GNUNET_free(ic); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * Close the existing connection to PEERSTORE and reconnect. | 287 | * Close the existing connection to PEERSTORE and reconnect. |
309 | * | 288 | * |
310 | * @param h handle to the service | 289 | * @param h handle to the service |
@@ -312,7 +291,6 @@ cleanup_handle(struct GNUNET_PEERSTORE_Handle *h) | |||
312 | static void | 291 | static void |
313 | reconnect (struct GNUNET_PEERSTORE_Handle *h) | 292 | reconnect (struct GNUNET_PEERSTORE_Handle *h) |
314 | { | 293 | { |
315 | |||
316 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Reconnecting...\n"); | 294 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Reconnecting...\n"); |
317 | if (NULL != h->mq) | 295 | if (NULL != h->mq) |
318 | { | 296 | { |
@@ -324,12 +302,13 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h) | |||
324 | GNUNET_CLIENT_disconnect (h->client); | 302 | GNUNET_CLIENT_disconnect (h->client); |
325 | h->client = NULL; | 303 | h->client = NULL; |
326 | } | 304 | } |
327 | cleanup_handle(h); | ||
328 | h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg); | 305 | h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg); |
306 | //FIXME: retry connecting if fails again (client == NULL) | ||
329 | h->mq = GNUNET_MQ_queue_for_connection_client(h->client, | 307 | h->mq = GNUNET_MQ_queue_for_connection_client(h->client, |
330 | mq_handlers, | 308 | mq_handlers, |
331 | &handle_client_error, | 309 | &handle_client_error, |
332 | h); | 310 | h); |
311 | //FIXME: resend pending requests after reconnecting | ||
333 | 312 | ||
334 | } | 313 | } |
335 | 314 | ||
@@ -373,6 +352,11 @@ GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
373 | void | 352 | void |
374 | GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h) | 353 | GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h) |
375 | { | 354 | { |
355 | if(NULL != h->watches) | ||
356 | { | ||
357 | GNUNET_CONTAINER_multihashmap_destroy(h->watches); | ||
358 | h->watches = NULL; | ||
359 | } | ||
376 | if(NULL != h->mq) | 360 | if(NULL != h->mq) |
377 | { | 361 | { |
378 | GNUNET_MQ_destroy(h->mq); | 362 | GNUNET_MQ_destroy(h->mq); |
@@ -383,7 +367,6 @@ GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h) | |||
383 | GNUNET_CLIENT_disconnect (h->client); | 367 | GNUNET_CLIENT_disconnect (h->client); |
384 | h->client = NULL; | 368 | h->client = NULL; |
385 | } | 369 | } |
386 | cleanup_handle(h); | ||
387 | GNUNET_free(h); | 370 | GNUNET_free(h); |
388 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnected, BYE!\n"); | 371 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnected, BYE!\n"); |
389 | } | 372 | } |
@@ -655,7 +638,7 @@ GNUNET_PEERSTORE_iterate_cancel (struct GNUNET_PEERSTORE_IterateContext *ic) | |||
655 | */ | 638 | */ |
656 | struct GNUNET_PEERSTORE_IterateContext * | 639 | struct GNUNET_PEERSTORE_IterateContext * |
657 | GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h, | 640 | GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h, |
658 | char *sub_system, | 641 | const char *sub_system, |
659 | const struct GNUNET_PeerIdentity *peer, | 642 | const struct GNUNET_PeerIdentity *peer, |
660 | const char *key, | 643 | const char *key, |
661 | struct GNUNET_TIME_Relative timeout, | 644 | struct GNUNET_TIME_Relative timeout, |
@@ -698,7 +681,54 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h, | |||
698 | */ | 681 | */ |
699 | void handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg) | 682 | void handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg) |
700 | { | 683 | { |
684 | /*struct GNUNET_PEERSTORE_Handle *h = cls; | ||
685 | struct GNUNET_PEERSTORE_WatchContext *wc; | ||
686 | GNUNET_PEERSTORE_Processor callback; | ||
687 | void *callback_cls; | ||
688 | |||
689 | |||
690 | |||
691 | struct GNUNET_PEERSTORE_IterateContext *ic; | ||
692 | uint16_t msg_type; | ||
693 | struct GNUNET_PEERSTORE_Record *record; | ||
694 | int continue_iter; | ||
695 | |||
696 | ic = h->iterate_head; | ||
697 | if(NULL == ic) | ||
698 | { | ||
699 | LOG(GNUNET_ERROR_TYPE_ERROR, "Unexpected iteration response, this should not happen.\n"); | ||
700 | reconnect(h); | ||
701 | return; | ||
702 | } | ||
703 | callback = ic->callback; | ||
704 | callback_cls = ic->callback_cls; | ||
705 | if(NULL == msg) * Connection error * | ||
706 | { | ||
701 | 707 | ||
708 | if(NULL != callback) | ||
709 | callback(callback_cls, NULL, | ||
710 | _("Error communicating with `PEERSTORE' service.")); | ||
711 | reconnect(h); | ||
712 | return; | ||
713 | } | ||
714 | msg_type = ntohs(msg->type); | ||
715 | if(GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END == msg_type) | ||
716 | { | ||
717 | GNUNET_PEERSTORE_iterate_cancel(ic); | ||
718 | if(NULL != callback) | ||
719 | callback(callback_cls, NULL, NULL); | ||
720 | return; | ||
721 | } | ||
722 | if(NULL != callback) | ||
723 | { | ||
724 | record = PEERSTORE_parse_record_message(msg); | ||
725 | if(NULL == record) | ||
726 | continue_iter = callback(callback_cls, record, _("Received a malformed response from service.")); | ||
727 | else | ||
728 | continue_iter = callback(callback_cls, record, NULL); | ||
729 | if(GNUNET_NO == continue_iter) | ||
730 | ic->callback = NULL; | ||
731 | }*/ | ||
702 | } | 732 | } |
703 | 733 | ||
704 | /** | 734 | /** |
@@ -715,6 +745,36 @@ void watch_request_sent (void *cls) | |||
715 | } | 745 | } |
716 | 746 | ||
717 | /** | 747 | /** |
748 | * Cancel a watch request | ||
749 | * | ||
750 | * @wc handle to the watch request | ||
751 | */ | ||
752 | void | ||
753 | GNUNET_PEERSTORE_watch_cancel(struct GNUNET_PEERSTORE_WatchContext *wc) | ||
754 | { | ||
755 | struct GNUNET_PEERSTORE_Handle *h = wc->h; | ||
756 | struct GNUNET_MQ_Envelope *ev; | ||
757 | struct StoreKeyHashMessage *hm; | ||
758 | |||
759 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Canceling watch.\n"); | ||
760 | if(GNUNET_YES == wc->request_sent) /* If request already sent to service, send a cancel request. */ | ||
761 | { | ||
762 | ev = GNUNET_MQ_msg(hm, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL); | ||
763 | GNUNET_MQ_send(h->mq, ev); | ||
764 | wc->callback = NULL; | ||
765 | wc->callback_cls = NULL; | ||
766 | } | ||
767 | if(NULL != wc->ev) | ||
768 | { | ||
769 | GNUNET_MQ_send_cancel(wc->ev); | ||
770 | wc->ev = NULL; | ||
771 | } | ||
772 | GNUNET_CONTAINER_multihashmap_remove(h->watches, &wc->keyhash, wc); | ||
773 | GNUNET_free(wc); | ||
774 | |||
775 | } | ||
776 | |||
777 | /** | ||
718 | * Request watching a given key | 778 | * Request watching a given key |
719 | * User will be notified with any new values added to key | 779 | * User will be notified with any new values added to key |
720 | * | 780 | * |
@@ -728,28 +788,28 @@ void watch_request_sent (void *cls) | |||
728 | */ | 788 | */ |
729 | struct GNUNET_PEERSTORE_WatchContext * | 789 | struct GNUNET_PEERSTORE_WatchContext * |
730 | GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h, | 790 | GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h, |
731 | char *sub_system, | 791 | const char *sub_system, |
732 | const struct GNUNET_PeerIdentity *peer, | 792 | const struct GNUNET_PeerIdentity *peer, |
733 | const char *key, | 793 | const char *key, |
734 | GNUNET_PEERSTORE_Processor callback, void *callback_cls) | 794 | GNUNET_PEERSTORE_Processor callback, void *callback_cls) |
735 | { | 795 | { |
736 | struct GNUNET_MQ_Envelope *ev; | 796 | struct GNUNET_MQ_Envelope *ev; |
797 | struct StoreKeyHashMessage *hm; | ||
737 | struct GNUNET_PEERSTORE_WatchContext *wc; | 798 | struct GNUNET_PEERSTORE_WatchContext *wc; |
738 | 799 | ||
739 | ev = PEERSTORE_create_record_mq_envelope(sub_system, | 800 | ev = GNUNET_MQ_msg(hm, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH); |
740 | peer, | 801 | PEERSTORE_hash_key(sub_system, peer, key, &hm->keyhash); |
741 | key, | ||
742 | NULL, | ||
743 | 0, | ||
744 | NULL, | ||
745 | GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH); | ||
746 | wc = GNUNET_new(struct GNUNET_PEERSTORE_WatchContext); | 802 | wc = GNUNET_new(struct GNUNET_PEERSTORE_WatchContext); |
747 | wc->callback = callback; | 803 | wc->callback = callback; |
748 | wc->callback_cls = callback_cls; | 804 | wc->callback_cls = callback_cls; |
749 | wc->ev = ev; | 805 | wc->ev = ev; |
750 | wc->h = h; | 806 | wc->h = h; |
751 | wc->request_sent = GNUNET_NO; | 807 | wc->request_sent = GNUNET_NO; |
752 | GNUNET_CONTAINER_DLL_insert(h->watch_head, h->watch_tail, wc); | 808 | wc->keyhash = hm->keyhash; |
809 | if(NULL == h->watches) | ||
810 | h->watches = GNUNET_CONTAINER_multihashmap_create(5, GNUNET_NO); | ||
811 | GNUNET_CONTAINER_multihashmap_put(h->watches, &wc->keyhash, | ||
812 | wc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
753 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 813 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
754 | "Sending a watch request for sub system `%s'.\n", sub_system); | 814 | "Sending a watch request for sub system `%s'.\n", sub_system); |
755 | GNUNET_MQ_notify_sent(ev, &watch_request_sent, wc); | 815 | GNUNET_MQ_notify_sent(ev, &watch_request_sent, wc); |
diff --git a/src/peerstore/peerstore_common.c b/src/peerstore/peerstore_common.c index 5783973b6..2b62abf19 100644 --- a/src/peerstore/peerstore_common.c +++ b/src/peerstore/peerstore_common.c | |||
@@ -26,6 +26,38 @@ | |||
26 | #include "peerstore_common.h" | 26 | #include "peerstore_common.h" |
27 | 27 | ||
28 | /** | 28 | /** |
29 | * Creates a hash of the given key combination | ||
30 | * | ||
31 | */ | ||
32 | void | ||
33 | PEERSTORE_hash_key(const char *sub_system, | ||
34 | const struct GNUNET_PeerIdentity *peer, | ||
35 | const char *key, | ||
36 | struct GNUNET_HashCode *ret) | ||
37 | { | ||
38 | size_t sssize; | ||
39 | size_t psize; | ||
40 | size_t ksize; | ||
41 | size_t totalsize; | ||
42 | void *block; | ||
43 | void *blockptr; | ||
44 | |||
45 | sssize = strlen(sub_system) + 1; | ||
46 | psize = sizeof(struct GNUNET_PeerIdentity); | ||
47 | ksize = strlen(sub_system) + 1; | ||
48 | totalsize = sssize + psize + ksize; | ||
49 | block = GNUNET_malloc(totalsize); | ||
50 | blockptr = block; | ||
51 | memcpy(blockptr, sub_system, sssize); | ||
52 | blockptr += sssize; | ||
53 | memcpy(blockptr, peer, psize); | ||
54 | blockptr += psize; | ||
55 | memcpy(blockptr, key, ksize); | ||
56 | GNUNET_CRYPTO_hash(block, totalsize, ret); | ||
57 | GNUNET_free(block); | ||
58 | } | ||
59 | |||
60 | /** | ||
29 | * Creates a record message ready to be sent | 61 | * Creates a record message ready to be sent |
30 | * | 62 | * |
31 | * @param sub_system sub system string | 63 | * @param sub_system sub system string |
diff --git a/src/peerstore/peerstore_common.h b/src/peerstore/peerstore_common.h index cd918497b..20cb9c0e7 100644 --- a/src/peerstore/peerstore_common.h +++ b/src/peerstore/peerstore_common.h | |||
@@ -27,6 +27,16 @@ | |||
27 | #include "peerstore.h" | 27 | #include "peerstore.h" |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * Creates a hash of the given key combination | ||
31 | * | ||
32 | */ | ||
33 | void | ||
34 | PEERSTORE_hash_key(const char *sub_system, | ||
35 | const struct GNUNET_PeerIdentity *peer, | ||
36 | const char *key, | ||
37 | struct GNUNET_HashCode *ret); | ||
38 | |||
39 | /** | ||
30 | * Creates a record message ready to be sent | 40 | * Creates a record message ready to be sent |
31 | * | 41 | * |
32 | * @param sub_system sub system string | 42 | * @param sub_system sub system string |
diff --git a/src/peerstore/test_peerstore_api.c b/src/peerstore/test_peerstore_api.c index fe62933e7..7a512f664 100644 --- a/src/peerstore/test_peerstore_api.c +++ b/src/peerstore/test_peerstore_api.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include "gnunet_peerstore_service.h" | 27 | #include "gnunet_peerstore_service.h" |
28 | #include <inttypes.h> | 28 | #include <inttypes.h> |
29 | 29 | ||
30 | //TODO: test single cycle of watch, store, iterate | ||
31 | |||
30 | static int ok = 1; | 32 | static int ok = 1; |
31 | 33 | ||
32 | static int counter = 0; | 34 | static int counter = 0; |
@@ -76,6 +78,25 @@ void store_cont(void *cls, int success) | |||
76 | NULL); | 78 | NULL); |
77 | } | 79 | } |
78 | 80 | ||
81 | int watch_cb (void *cls, | ||
82 | struct GNUNET_PEERSTORE_Record *record, | ||
83 | char *emsg) | ||
84 | { | ||
85 | if(NULL != emsg) | ||
86 | { | ||
87 | printf("Error received: %s.\n", emsg); | ||
88 | return GNUNET_YES; | ||
89 | } | ||
90 | |||
91 | printf("Watch Record:\n"); | ||
92 | printf("Sub system: %s\n", record->sub_system); | ||
93 | printf("Peer: %s\n", GNUNET_i2s (record->peer)); | ||
94 | printf("Key: %s\n", record->key); | ||
95 | printf("Value: %.*s\n", (int)record->value_size, (char *)record->value); | ||
96 | printf("Expiry: %" PRIu64 "\n", record->expiry->abs_value_us); | ||
97 | return GNUNET_YES; | ||
98 | } | ||
99 | |||
79 | static void | 100 | static void |
80 | run (void *cls, | 101 | run (void *cls, |
81 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 102 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
@@ -91,6 +112,12 @@ run (void *cls, | |||
91 | expiry = GNUNET_TIME_absolute_get(); | 112 | expiry = GNUNET_TIME_absolute_get(); |
92 | h = GNUNET_PEERSTORE_connect(cfg); | 113 | h = GNUNET_PEERSTORE_connect(cfg); |
93 | GNUNET_assert(NULL != h); | 114 | GNUNET_assert(NULL != h); |
115 | GNUNET_PEERSTORE_watch(h, | ||
116 | "peerstore-test", | ||
117 | &pid, | ||
118 | "peerstore-test-key", | ||
119 | &watch_cb, | ||
120 | NULL); | ||
94 | GNUNET_PEERSTORE_store(h, | 121 | GNUNET_PEERSTORE_store(h, |
95 | "peerstore-test", | 122 | "peerstore-test", |
96 | &pid, | 123 | &pid, |
@@ -103,6 +130,17 @@ run (void *cls, | |||
103 | 130 | ||
104 | } | 131 | } |
105 | 132 | ||
133 | int iterator (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
134 | { | ||
135 | struct GNUNET_CONTAINER_MultiHashMap *map = cls; | ||
136 | uint32_t *x = value; | ||
137 | |||
138 | printf("Received value: %d\n", *x); | ||
139 | if(*x == 2) | ||
140 | GNUNET_CONTAINER_multihashmap_remove(map, key, value); | ||
141 | return GNUNET_YES; | ||
142 | } | ||
143 | |||
106 | int | 144 | int |
107 | main (int argc, char *argv[]) | 145 | main (int argc, char *argv[]) |
108 | { | 146 | { |