diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-09-24 11:58:31 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-09-24 11:58:31 +0000 |
commit | 3bca0a62abc14e5fe36e1c80ff487e0051dad562 (patch) | |
tree | 25a9dc36162d498910f6e41aa85a0d3863e0c1c0 /src | |
parent | d02c15600b668a30e091d2c5c59d918bb1e4fee7 (diff) | |
download | gnunet-3bca0a62abc14e5fe36e1c80ff487e0051dad562.tar.gz gnunet-3bca0a62abc14e5fe36e1c80ff487e0051dad562.zip |
migrate peerstore to new service MQ API
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_peerstore_plugin.h | 33 | ||||
-rw-r--r-- | src/include/gnunet_peerstore_service.h | 5 | ||||
-rw-r--r-- | src/peerstore/gnunet-service-peerstore.c | 540 | ||||
-rw-r--r-- | src/peerstore/peerstore.h | 7 | ||||
-rw-r--r-- | src/peerstore/peerstore_api.c | 20 | ||||
-rw-r--r-- | src/peerstore/peerstore_common.c | 94 | ||||
-rw-r--r-- | src/peerstore/peerstore_common.h | 38 | ||||
-rw-r--r-- | src/peerstore/test_peerstore_api_watch.c | 53 |
8 files changed, 376 insertions, 414 deletions
diff --git a/src/include/gnunet_peerstore_plugin.h b/src/include/gnunet_peerstore_plugin.h index 65359aefd..1d731f2cc 100644 --- a/src/include/gnunet_peerstore_plugin.h +++ b/src/include/gnunet_peerstore_plugin.h | |||
@@ -72,15 +72,15 @@ struct GNUNET_PEERSTORE_PluginFunctions | |||
72 | */ | 72 | */ |
73 | int | 73 | int |
74 | (*store_record) (void *cls, | 74 | (*store_record) (void *cls, |
75 | const char *sub_system, | 75 | const char *sub_system, |
76 | const struct GNUNET_PeerIdentity *peer, | 76 | const struct GNUNET_PeerIdentity *peer, |
77 | const char *key, | 77 | const char *key, |
78 | const void *value, | 78 | const void *value, |
79 | size_t size, | 79 | size_t size, |
80 | struct GNUNET_TIME_Absolute expiry, | 80 | struct GNUNET_TIME_Absolute expiry, |
81 | enum GNUNET_PEERSTORE_StoreOption options, | 81 | enum GNUNET_PEERSTORE_StoreOption options, |
82 | GNUNET_PEERSTORE_Continuation cont, | 82 | GNUNET_PEERSTORE_Continuation cont, |
83 | void *cont_cls); | 83 | void *cont_cls); |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * Iterate over the records given an optional peer id | 86 | * Iterate over the records given an optional peer id |
@@ -98,10 +98,11 @@ struct GNUNET_PEERSTORE_PluginFunctions | |||
98 | */ | 98 | */ |
99 | int | 99 | int |
100 | (*iterate_records) (void *cls, | 100 | (*iterate_records) (void *cls, |
101 | const char *sub_system, | 101 | const char *sub_system, |
102 | const struct GNUNET_PeerIdentity *peer, | 102 | const struct GNUNET_PeerIdentity *peer, |
103 | const char *key, | 103 | const char *key, |
104 | GNUNET_PEERSTORE_Processor iter, void *iter_cls); | 104 | GNUNET_PEERSTORE_Processor iter, |
105 | void *iter_cls); | ||
105 | 106 | ||
106 | /** | 107 | /** |
107 | * Delete expired records (expiry < now) | 108 | * Delete expired records (expiry < now) |
@@ -115,9 +116,9 @@ struct GNUNET_PEERSTORE_PluginFunctions | |||
115 | */ | 116 | */ |
116 | int | 117 | int |
117 | (*expire_records) (void *cls, | 118 | (*expire_records) (void *cls, |
118 | struct GNUNET_TIME_Absolute now, | 119 | struct GNUNET_TIME_Absolute now, |
119 | GNUNET_PEERSTORE_Continuation cont, | 120 | GNUNET_PEERSTORE_Continuation cont, |
120 | void *cont_cls); | 121 | void *cont_cls); |
121 | 122 | ||
122 | }; | 123 | }; |
123 | 124 | ||
diff --git a/src/include/gnunet_peerstore_service.h b/src/include/gnunet_peerstore_service.h index 202e0fd1a..3cafe70b8 100644 --- a/src/include/gnunet_peerstore_service.h +++ b/src/include/gnunet_peerstore_service.h | |||
@@ -109,9 +109,10 @@ struct GNUNET_PEERSTORE_Record | |||
109 | struct GNUNET_TIME_Absolute *expiry; | 109 | struct GNUNET_TIME_Absolute *expiry; |
110 | 110 | ||
111 | /** | 111 | /** |
112 | * Client from which this record originated | 112 | * Client from which this record originated. |
113 | * NOTE: This is internal to the service. | ||
113 | */ | 114 | */ |
114 | struct GNUNET_SERVER_Client *client; | 115 | struct GNUNET_SERVICE_Client *client; |
115 | }; | 116 | }; |
116 | 117 | ||
117 | 118 | ||
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 | */ | ||
35 | struct 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; | |||
76 | static struct GNUNET_CONTAINER_MultiHashMap *watchers; | 56 | static struct GNUNET_CONTAINER_MultiHashMap *watchers; |
77 | 57 | ||
78 | /** | 58 | /** |
79 | * Our notification context. | ||
80 | */ | ||
81 | static struct GNUNET_SERVER_NotificationContext *nc; | ||
82 | |||
83 | /** | ||
84 | * Head of linked list of connected clients | ||
85 | */ | ||
86 | static struct ClientEntry *client_head; | ||
87 | |||
88 | /** | ||
89 | * Tail of linked list of connected clients | ||
90 | */ | ||
91 | static struct ClientEntry *client_tail; | ||
92 | |||
93 | /** | ||
94 | * Task run to clean up expired records. | 59 | * Task run to clean up expired records. |
95 | */ | 60 | */ |
96 | static struct GNUNET_SCHEDULER_Task *expire_task; | 61 | static struct GNUNET_SCHEDULER_Task *expire_task; |
@@ -101,6 +66,12 @@ static struct GNUNET_SCHEDULER_Task *expire_task; | |||
101 | static int in_shutdown; | 66 | static int in_shutdown; |
102 | 67 | ||
103 | /** | 68 | /** |
69 | * Number of connected clients. | ||
70 | */ | ||
71 | static unsigned int num_clients; | ||
72 | |||
73 | |||
74 | /** | ||
104 | * Perform the actual shutdown operations | 75 | * Perform the actual shutdown operations |
105 | */ | 76 | */ |
106 | static void | 77 | static 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 | |||
140 | shutdown_task (void *cls) | 108 | shutdown_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 */ |
149 | static void | 117 | static void |
150 | expire_records_continuation (void *cls, int success); | 118 | expire_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 | */ | ||
179 | static void * | ||
180 | client_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 | */ |
206 | static int | 197 | static int |
207 | client_disconnect_it (void *cls, const struct GNUNET_HashCode *key, void *value) | 198 | client_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 | */ |
221 | static void | 219 | static void |
222 | handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | 220 | client_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 | */ |
254 | static void | 245 | static void |
255 | record_iterator (void *cls, const struct GNUNET_PEERSTORE_Record *record, | 246 | record_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 | */ |
297 | static int | 292 | static int |
298 | watch_notifier_it (void *cls, const struct GNUNET_HashCode *key, void *value) | 293 | watch_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 | */ |
341 | static void | 344 | static void |
342 | handle_watch_cancel (void *cls, struct GNUNET_SERVER_Client *client, | 345 | handle_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 | */ |
361 | static void | 372 | static void |
362 | handle_watch (void *cls, struct GNUNET_SERVER_Client *client, | 373 | handle_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 | */ |
384 | static void | 397 | static int |
385 | handle_iterate (void *cls, struct GNUNET_SERVER_Client *client, | 398 | check_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 | */ | ||
425 | static void | ||
426 | handle_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 | */ |
429 | static void | 459 | static void |
430 | store_record_continuation (void *cls, int success) | 460 | store_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 | */ |
450 | static void | 485 | static int |
451 | handle_store (void *cls, struct GNUNET_SERVER_Client *client, | 486 | check_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 | */ | ||
516 | static void | ||
517 | handle_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 | */ | ||
503 | static struct ClientEntry * | ||
504 | make_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 | */ | ||
533 | static void | ||
534 | handle_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 | */ |
548 | static void | 557 | static void |
549 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 558 | run (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 | */ |
603 | int | 604 | GNUNET_SERVICE_MAIN |
604 | main (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 | 36 | struct 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 | */ |
580 | static int | 580 | static int |
581 | check_iterate_result (void *cls, | 581 | check_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 | */ |
595 | static void | 595 | static void |
596 | handle_iterate_result (void *cls, | 596 | handle_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 | */ |
726 | static int | 726 | static int |
727 | check_watch_record (void *cls, | 727 | check_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 | */ |
741 | static void | 741 | static void |
742 | handle_watch_record (void *cls, | 742 | handle_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 | */ |
32 | void | 32 | void |
33 | PEERSTORE_hash_key (const char *sub_system, | 33 | PEERSTORE_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 | */ | ||
72 | struct StoreRecordMessage * | ||
73 | PEERSTORE_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, | |||
131 | struct GNUNET_MQ_Envelope * | 74 | struct GNUNET_MQ_Envelope * |
132 | PEERSTORE_create_record_mq_envelope (const char *sub_system, | 75 | PEERSTORE_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 | */ |
184 | struct GNUNET_PEERSTORE_Record * | 128 | struct GNUNET_PEERSTORE_Record * |
185 | PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message) | 129 | PEERSTORE_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 | */ |
34 | void | 33 | void |
35 | PEERSTORE_hash_key (const char *sub_system, | 34 | PEERSTORE_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 | */ | ||
51 | struct StoreRecordMessage * | ||
52 | PEERSTORE_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, | |||
72 | struct GNUNET_MQ_Envelope * | 53 | struct GNUNET_MQ_Envelope * |
73 | PEERSTORE_create_record_mq_envelope (const char *sub_system, | 54 | PEERSTORE_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 | */ |
87 | struct GNUNET_PEERSTORE_Record * | 70 | struct GNUNET_PEERSTORE_Record * |
88 | PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message); | 71 | PEERSTORE_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 | */ |
95 | void | 79 | void |
96 | PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record); | 80 | PEERSTORE_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 | |||
29 | static int ok = 1; | 30 | static int ok = 1; |
30 | 31 | ||
31 | static struct GNUNET_PEERSTORE_Handle *h; | 32 | static struct GNUNET_PEERSTORE_Handle *h; |
32 | 33 | ||
33 | static char *ss = "test_peerstore_api_watch"; | 34 | static char *ss = "test_peerstore_api_watch"; |
34 | static struct GNUNET_PeerIdentity p; | 35 | |
35 | static char *k = "test_peerstore_api_watch_key"; | 36 | static char *k = "test_peerstore_api_watch_key"; |
37 | |||
36 | static char *val = "test_peerstore_api_watch_val"; | 38 | static char *val = "test_peerstore_api_watch_val"; |
37 | 39 | ||
40 | |||
38 | static void | 41 | static void |
39 | watch_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, | 42 | watch_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 | ||
50 | static void | 56 | static void |
51 | run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, | 57 | run (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 | ||
64 | int | 87 | int |
65 | main (int argc, char *argv[]) | 88 | main (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 | } |