diff options
author | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
commit | eb9556bf2983ca19a5cbcf7cf460a0b2509b290a (patch) | |
tree | 285d31e951f7ecf9308b22257adcadd5b07d80ea | |
parent | 37bafa60a6f0e447cb5b61547404f0902fa7ad41 (diff) | |
download | gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.tar.gz gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.zip |
PSYCstore SQLite backend; API fixes/enhancements
-rw-r--r-- | src/include/gnunet_multicast_service.h | 86 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 2 | ||||
-rw-r--r-- | src/include/gnunet_psyc_service.h | 47 | ||||
-rw-r--r-- | src/include/gnunet_psycstore_plugin.h | 120 | ||||
-rw-r--r-- | src/include/gnunet_psycstore_service.h | 78 | ||||
-rw-r--r-- | src/include/gnunet_social_service.h | 63 | ||||
-rw-r--r-- | src/psycstore/Makefile.am | 13 | ||||
-rw-r--r-- | src/psycstore/gnunet-service-psycstore.c | 59 | ||||
-rw-r--r-- | src/psycstore/plugin_psycstore_sqlite.c | 1172 | ||||
-rw-r--r-- | src/psycstore/psycstore.conf | 2 | ||||
-rw-r--r-- | src/psycstore/psycstore.h | 28 | ||||
-rw-r--r-- | src/psycstore/psycstore_api.c | 44 | ||||
-rw-r--r-- | src/psycstore/test_plugin_psycstore.c | 375 | ||||
-rw-r--r-- | src/psycstore/test_plugin_psycstore_sqlite.conf | 2 | ||||
-rw-r--r-- | src/psycstore/test_psycstore.c | 33 | ||||
-rw-r--r-- | src/psycstore/test_psycstore.conf | 11 |
16 files changed, 1734 insertions, 401 deletions
diff --git a/src/include/gnunet_multicast_service.h b/src/include/gnunet_multicast_service.h index e1dec7b85..1c23af2f0 100644 --- a/src/include/gnunet_multicast_service.h +++ b/src/include/gnunet_multicast_service.h | |||
@@ -101,7 +101,7 @@ struct GNUNET_MULTICAST_MessageHeader | |||
101 | * unicast requests from members. Updated at each hop and thus not signed and | 101 | * unicast requests from members. Updated at each hop and thus not signed and |
102 | * not secure. | 102 | * not secure. |
103 | */ | 103 | */ |
104 | uint32_t hop_counter GNUNET_PACKED; | 104 | uint32_t hop_counter; |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * ECC signature of the message fragment. | 107 | * ECC signature of the message fragment. |
@@ -118,19 +118,19 @@ struct GNUNET_MULTICAST_MessageHeader | |||
118 | /** | 118 | /** |
119 | * Number of the message fragment, monotonically increasing. | 119 | * Number of the message fragment, monotonically increasing. |
120 | */ | 120 | */ |
121 | uint64_t fragment_id GNUNET_PACKED; | 121 | uint64_t fragment_id; |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * Byte offset of this @e fragment of the @e message. | 124 | * Byte offset of this @e fragment of the @e message. |
125 | */ | 125 | */ |
126 | uint64_t fragment_offset GNUNET_PACKED; | 126 | uint64_t fragment_offset; |
127 | 127 | ||
128 | /** | 128 | /** |
129 | * Number of the message this fragment belongs to. | 129 | * Number of the message this fragment belongs to. |
130 | * | 130 | * |
131 | * Set in GNUNET_MULTICAST_origin_to_all(). | 131 | * Set in GNUNET_MULTICAST_origin_to_all(). |
132 | */ | 132 | */ |
133 | uint64_t message_id GNUNET_PACKED; | 133 | uint64_t message_id; |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * Counter that monotonically increases whenever a member parts the group. | 136 | * Counter that monotonically increases whenever a member parts the group. |
@@ -142,15 +142,15 @@ struct GNUNET_MULTICAST_MessageHeader | |||
142 | * is still the same before and after the missed messages, it means that no | 142 | * is still the same before and after the missed messages, it means that no |
143 | * @e join or @e part operations happened during the missed messages. | 143 | * @e join or @e part operations happened during the missed messages. |
144 | */ | 144 | */ |
145 | uint64_t group_generation GNUNET_PACKED; | 145 | uint64_t group_generation; |
146 | 146 | ||
147 | /** | 147 | /** |
148 | * Flags for this message fragment. | 148 | * Flags for this message fragment. |
149 | */ | 149 | */ |
150 | enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED; | 150 | uint32_t flags; |
151 | 151 | ||
152 | /* Followed by message body. */ | 152 | /* Followed by message body. */ |
153 | }; | 153 | } GNUNET_PACKED; |
154 | 154 | ||
155 | GNUNET_NETWORK_STRUCT_END | 155 | GNUNET_NETWORK_STRUCT_END |
156 | 156 | ||
@@ -309,7 +309,7 @@ struct GNUNET_MULTICAST_ReplayHandle; | |||
309 | 309 | ||
310 | /** | 310 | /** |
311 | * Functions with this signature are called whenever the multicast service needs | 311 | * Functions with this signature are called whenever the multicast service needs |
312 | * a message to be replayed. | 312 | * a message fragemnt to be replayed by fragment_id. |
313 | * | 313 | * |
314 | * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE | 314 | * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE |
315 | * (with a message or an error); however, if the origin is destroyed or the | 315 | * (with a message or an error); however, if the origin is destroyed or the |
@@ -331,7 +331,7 @@ typedef void | |||
331 | 331 | ||
332 | /** | 332 | /** |
333 | * Functions with this signature are called whenever the multicast service needs | 333 | * Functions with this signature are called whenever the multicast service needs |
334 | * a message to be replayed. | 334 | * a message fragment to be replayed by message_id and fragment_offset. |
335 | * | 335 | * |
336 | * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE | 336 | * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE |
337 | * (with a message or an error); however, if the origin is destroyed or the | 337 | * (with a message or an error); however, if the origin is destroyed or the |
@@ -404,9 +404,9 @@ enum GNUNET_MULTICAST_ReplayErrorCode | |||
404 | * @param ec Error code. | 404 | * @param ec Error code. |
405 | */ | 405 | */ |
406 | void | 406 | void |
407 | GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh, | 407 | GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh, |
408 | const struct GNUNET_MessageHeader *msg, | 408 | const struct GNUNET_MessageHeader *msg, |
409 | enum GNUNET_MULTICAST_ReplayErrorCode ec); | 409 | enum GNUNET_MULTICAST_ReplayErrorCode ec); |
410 | 410 | ||
411 | 411 | ||
412 | /** | 412 | /** |
@@ -417,7 +417,7 @@ GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh, | |||
417 | * @param rh Replay session to end. | 417 | * @param rh Replay session to end. |
418 | */ | 418 | */ |
419 | void | 419 | void |
420 | GNUNET_MULTICAST_replay_end (struct GNUNET_MULTICAST_ReplayHandle *rh); | 420 | GNUNET_MULTICAST_replay_response_end (struct GNUNET_MULTICAST_ReplayHandle *rh); |
421 | 421 | ||
422 | 422 | ||
423 | /** | 423 | /** |
@@ -426,9 +426,9 @@ GNUNET_MULTICAST_replay_end (struct GNUNET_MULTICAST_ReplayHandle *rh); | |||
426 | * @see GNUNET_MULTICAST_replay2() | 426 | * @see GNUNET_MULTICAST_replay2() |
427 | */ | 427 | */ |
428 | typedef int | 428 | typedef int |
429 | (*GNUNET_MULTICAST_ReplayTransmitNotify)(void *cls, | 429 | (*GNUNET_MULTICAST_ReplayTransmitNotify) (void *cls, |
430 | size_t *data_size, | 430 | size_t *data_size, |
431 | void *data); | 431 | void *data); |
432 | 432 | ||
433 | 433 | ||
434 | /** | 434 | /** |
@@ -439,9 +439,9 @@ typedef int | |||
439 | * @param notify_cls Closure for @a notify. | 439 | * @param notify_cls Closure for @a notify. |
440 | */ | 440 | */ |
441 | void | 441 | void |
442 | GNUNET_MULTICAST_replay2 (struct GNUNET_MULTICAST_ReplayHandle *rh, | 442 | GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh, |
443 | GNUNET_MULTICAST_ReplayTransmitNotify notify, | 443 | GNUNET_MULTICAST_ReplayTransmitNotify notify, |
444 | void *notify_cls); | 444 | void *notify_cls); |
445 | 445 | ||
446 | 446 | ||
447 | /** | 447 | /** |
@@ -465,7 +465,8 @@ GNUNET_MULTICAST_replay2 (struct GNUNET_MULTICAST_ReplayHandle *rh, | |||
465 | * when restarting the origin. 0 for a new group. | 465 | * when restarting the origin. 0 for a new group. |
466 | * @param join_cb Function called to approve / disapprove joining of a peer. | 466 | * @param join_cb Function called to approve / disapprove joining of a peer. |
467 | * @param test_cb Function multicast can use to test group membership. | 467 | * @param test_cb Function multicast can use to test group membership. |
468 | * @param replay_cb Function that can be called to replay a message. | 468 | * @param replay_frag_cb Function that can be called to replay a message fragment. |
469 | * @param replay_msg_cb Function that can be called to replay a message. | ||
469 | * @param request_cb Function called with message fragments from group members. | 470 | * @param request_cb Function called with message fragments from group members. |
470 | * @param message_cb Function called with the message fragments sent to the | 471 | * @param message_cb Function called with the message fragments sent to the |
471 | * network by GNUNET_MULTICAST_origin_to_all(). These message fragments | 472 | * network by GNUNET_MULTICAST_origin_to_all(). These message fragments |
@@ -486,12 +487,13 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
486 | void *cls); | 487 | void *cls); |
487 | 488 | ||
488 | /** | 489 | /** |
489 | * Function called to provide data for a transmission from the origin to all members. | 490 | * Function called to provide data for a transmission from the origin to all |
491 | * members. | ||
490 | */ | 492 | */ |
491 | typedef int | 493 | typedef int |
492 | (*GNUNET_MULTICAST_OriginTransmitNotify)(void *cls, | 494 | (*GNUNET_MULTICAST_OriginTransmitNotify) (void *cls, |
493 | size_t *data_size, | 495 | size_t *data_size, |
494 | void *data); | 496 | void *data); |
495 | 497 | ||
496 | 498 | ||
497 | /** | 499 | /** |
@@ -568,15 +570,13 @@ GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin); | |||
568 | * @a relay (might, for example, contain a user, bind user | 570 | * @a relay (might, for example, contain a user, bind user |
569 | * identity/pseudonym to peer identity, application-level message to | 571 | * identity/pseudonym to peer identity, application-level message to |
570 | * origin, etc.). | 572 | * origin, etc.). |
571 | * @param max_known_fragment_id Largest known message fragment ID to the replay | ||
572 | * service; all messages with IDs larger than this ID will be replayed if | ||
573 | * possible (lower IDs will be considered known and thus only | ||
574 | * be replayed upon explicit request). | ||
575 | * FIXME: needed? can be optional or moved to a separate function. | ||
576 | * @param join_cb Function called to approve / disapprove joining of a peer. | 573 | * @param join_cb Function called to approve / disapprove joining of a peer. |
577 | * @param test_cb Function multicast can use to test group membership. | 574 | * @param test_cb Function multicast can use to test group membership. |
578 | * @param replay_cb Function that can be called to replay messages | 575 | * @param replay_frag_cb Function that can be called to replay message fragments |
579 | * this peer already knows from this group; NULL if this | 576 | * this peer already knows from this group. NULL if this |
577 | * client is unable to support replay. | ||
578 | * @param replay_msg_cb Function that can be called to replay message fragments | ||
579 | * this peer already knows from this group. NULL if this | ||
580 | * client is unable to support replay. | 580 | * client is unable to support replay. |
581 | * @param message_cb Function to be called for all message fragments we | 581 | * @param message_cb Function to be called for all message fragments we |
582 | * receive from the group, excluding those our @a replay_cb | 582 | * receive from the group, excluding those our @a replay_cb |
@@ -597,8 +597,8 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
597 | GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, | 597 | GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, |
598 | GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, | 598 | GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, |
599 | GNUNET_MULTICAST_MessageCallback message_cb, | 599 | GNUNET_MULTICAST_MessageCallback message_cb, |
600 | void *cls); | 600 | void *cls) |
601 | 601 | ; | |
602 | 602 | ||
603 | /** | 603 | /** |
604 | * Handle for a replay request. | 604 | * Handle for a replay request. |
@@ -633,16 +633,10 @@ GNUNET_MULTICAST_member_replay_fragment (struct GNUNET_MULTICAST_Member *member, | |||
633 | * needed and not known to the client. | 633 | * needed and not known to the client. |
634 | * | 634 | * |
635 | * @param member Membership handle. | 635 | * @param member Membership handle. |
636 | * @param fragment_id ID of a message fragment that this client would like to | 636 | * @param message_id ID of the message this client would like to see replayed. |
637 | see replayed. | 637 | * @param fragment_offset Offset of the fragment within the message to replay. |
638 | * @param message_id ID of a message that this client would like to see | ||
639 | * replayed. Typically only one of the @a fragment_id and @a message_id | ||
640 | * is given. Specifying a @a message_id would return the last fragment | ||
641 | * of the message, which allows requesting the preceding fragments of the | ||
642 | * message by looking at the @e fragment_delta header field. | ||
643 | * @param flags Additional flags for the replay request. It is used & defined | 638 | * @param flags Additional flags for the replay request. It is used & defined |
644 | * by the replay callback. E.g. the PSYC service would use this to | 639 | * by the replay callback. |
645 | * implement state synchronization. | ||
646 | * @param result_cb Function to be called for the replayed message. | 640 | * @param result_cb Function to be called for the replayed message. |
647 | * @param result_cb_cls Closure for @a message_cb. | 641 | * @param result_cb_cls Closure for @a message_cb. |
648 | * @return Replay request handle, NULL on error. | 642 | * @return Replay request handle, NULL on error. |
@@ -679,7 +673,7 @@ void | |||
679 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member); | 673 | GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member); |
680 | 674 | ||
681 | 675 | ||
682 | /** | 676 | /** |
683 | * Function called to provide data for a transmission from a member to the origin. | 677 | * Function called to provide data for a transmission from a member to the origin. |
684 | * | 678 | * |
685 | * @param cls closure | 679 | * @param cls closure |
@@ -688,9 +682,9 @@ GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member); | |||
688 | * @return number of bytes copied to data | 682 | * @return number of bytes copied to data |
689 | */ | 683 | */ |
690 | typedef int | 684 | typedef int |
691 | (*GNUNET_MULTICAST_MemberTransmitNotify)(void *cls, | 685 | (*GNUNET_MULTICAST_MemberTransmitNotify) (void *cls, |
692 | size_t *data_size, | 686 | size_t *data_size, |
693 | void *data); | 687 | void *data); |
694 | 688 | ||
695 | 689 | ||
696 | /** | 690 | /** |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index f7e65536b..1b231296f 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -1997,7 +1997,7 @@ extern "C" | |||
1997 | /** | 1997 | /** |
1998 | * Multicast message from the origin to all members. | 1998 | * Multicast message from the origin to all members. |
1999 | */ | 1999 | */ |
2000 | #define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE | 2000 | #define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE 700 |
2001 | 2001 | ||
2002 | /** | 2002 | /** |
2003 | * A unicast message from a group member to the origin. | 2003 | * A unicast message from a group member to the origin. |
diff --git a/src/include/gnunet_psyc_service.h b/src/include/gnunet_psyc_service.h index 8e43b387e..df7a6b4d9 100644 --- a/src/include/gnunet_psyc_service.h +++ b/src/include/gnunet_psyc_service.h | |||
@@ -208,9 +208,9 @@ struct GNUNET_PSYC_JoinHandle; | |||
208 | * @param modifier_count Number of elements in the @a modifiers array. | 208 | * @param modifier_count Number of elements in the @a modifiers array. |
209 | * @param modifiers State modifiers and transient variables for the message. | 209 | * @param modifiers State modifiers and transient variables for the message. |
210 | * @param data_offset Byte offset of @a data in the overall data of the method. | 210 | * @param data_offset Byte offset of @a data in the overall data of the method. |
211 | * @param data_size Number of bytes in @a data. | ||
212 | * @param data Data stream given to the method (might not be zero-terminated | 211 | * @param data Data stream given to the method (might not be zero-terminated |
213 | * if data is binary). | 212 | * if data is binary). |
213 | * @param data_size Number of bytes in @a data. | ||
214 | * @param frag Fragmentation status for the data. | 214 | * @param frag Fragmentation status for the data. |
215 | */ | 215 | */ |
216 | typedef int | 216 | typedef int |
@@ -221,8 +221,8 @@ typedef int | |||
221 | size_t modifier_count, | 221 | size_t modifier_count, |
222 | const struct GNUNET_ENV_Modifier *modifiers, | 222 | const struct GNUNET_ENV_Modifier *modifiers, |
223 | uint64_t data_offset, | 223 | uint64_t data_offset, |
224 | size_t data_size, | ||
225 | const void *data, | 224 | const void *data, |
225 | size_t data_size, | ||
226 | enum GNUNET_PSYC_MessageFlags flags); | 226 | enum GNUNET_PSYC_MessageFlags flags); |
227 | 227 | ||
228 | 228 | ||
@@ -234,9 +234,10 @@ typedef int | |||
234 | * @param method_name Method name in the join request. | 234 | * @param method_name Method name in the join request. |
235 | * @param variable_count Number of elements in the @a variables array. | 235 | * @param variable_count Number of elements in the @a variables array. |
236 | * @param variables Transient variables for the join request. | 236 | * @param variables Transient variables for the join request. |
237 | * @param data_size Number of bytes in @a data. | ||
238 | * @param data Data stream given to the method (might not be zero-terminated | 237 | * @param data Data stream given to the method (might not be zero-terminated |
239 | * if data is binary). | 238 | * if data is binary). |
239 | * @param data_size Number of bytes in @a data. | ||
240 | * @param jh Join handle to use with GNUNET_PSYC_join_decision() | ||
240 | */ | 241 | */ |
241 | typedef int | 242 | typedef int |
242 | (*GNUNET_PSYC_JoinCallback) (void *cls, | 243 | (*GNUNET_PSYC_JoinCallback) (void *cls, |
@@ -244,8 +245,8 @@ typedef int | |||
244 | const char *method_name, | 245 | const char *method_name, |
245 | size_t variable_count, | 246 | size_t variable_count, |
246 | const struct GNUNET_ENV_Modifier *variables, | 247 | const struct GNUNET_ENV_Modifier *variables, |
247 | size_t data_size, | ||
248 | const void *data, | 248 | const void *data, |
249 | size_t data_size, | ||
249 | struct GNUNET_PSYC_JoinHandle *jh); | 250 | struct GNUNET_PSYC_JoinHandle *jh); |
250 | 251 | ||
251 | 252 | ||
@@ -268,8 +269,8 @@ typedef int | |||
268 | * peer identity in this array. | 269 | * peer identity in this array. |
269 | * @param method_name Method name for the message transmitted with the response. | 270 | * @param method_name Method name for the message transmitted with the response. |
270 | * @param env Environment containing transient variables for the message, or NULL. | 271 | * @param env Environment containing transient variables for the message, or NULL. |
271 | * @param data_size Size of @a data. | ||
272 | * @param data Data of the message. | 272 | * @param data Data of the message. |
273 | * @param data_size Size of @a data. | ||
273 | */ | 274 | */ |
274 | void | 275 | void |
275 | GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, | 276 | GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, |
@@ -278,8 +279,8 @@ GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, | |||
278 | const struct GNUNET_PeerIdentity *relays, | 279 | const struct GNUNET_PeerIdentity *relays, |
279 | const char *method_name, | 280 | const char *method_name, |
280 | const struct GNUNET_ENV_Environment *env, | 281 | const struct GNUNET_ENV_Environment *env, |
281 | size_t data_size, | 282 | const void *data, |
282 | const void *data); | 283 | size_t data_size); |
283 | 284 | ||
284 | 285 | ||
285 | /** | 286 | /** |
@@ -333,21 +334,20 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
333 | * @param cls Closure. | 334 | * @param cls Closure. |
334 | * @param message_id Set to the unique message ID that was generated for | 335 | * @param message_id Set to the unique message ID that was generated for |
335 | * this message. | 336 | * this message. |
336 | * @param[in,out] data_size Initially set to the number of bytes available in @a data, | 337 | * @param[in,out] data_size Initially set to the number of bytes available in |
337 | * should be set to the number of bytes written to data (IN/OUT). | 338 | * @a data, should be set to the number of bytes written to data. |
338 | * @param[out] data Where to write the body of the message to give to the method; | 339 | * @param[out] data Where to write the body of the message to give to the |
339 | * function must copy at most @a *data_size bytes to @a data. | 340 | * method. The function must copy at most @a data_size bytes to @a data. |
340 | * @return #GNUNET_SYSERR on error (fatal, aborts transmission) | 341 | * @return #GNUNET_SYSERR on error (fatal, aborts transmission) |
341 | * #GNUNET_NO on success, if more data is to be transmitted later | 342 | * #GNUNET_NO on success, if more data is to be transmitted later |
342 | * (should be used if @a *data_size was not big enough to take all the data) | 343 | * (should be used if @a data_size was not big enough to take all the data) |
343 | * #GNUNET_YES if this completes the transmission (all data supplied) | 344 | * #GNUNET_YES if this completes the transmission (all data supplied) |
344 | */ | 345 | */ |
345 | typedef int | 346 | typedef int |
346 | (*GNUNET_PSYC_MasterTransmitNotify)(void *cls, | 347 | (*GNUNET_PSYC_MasterTransmitNotify) (void *cls, |
347 | uint64_t message_id, | 348 | uint64_t message_id, |
348 | size_t *data_size, | 349 | size_t *data_size, |
349 | void *data); | 350 | void *data); |
350 | |||
351 | 351 | ||
352 | 352 | ||
353 | /** | 353 | /** |
@@ -450,8 +450,8 @@ struct GNUNET_PSYC_Slave; | |||
450 | * @param cls Closure for @a method_cb and @a join_cb. | 450 | * @param cls Closure for @a method_cb and @a join_cb. |
451 | * @param method_name Method name for the join request. | 451 | * @param method_name Method name for the join request. |
452 | * @param env Environment containing transient variables for the request, or NULL. | 452 | * @param env Environment containing transient variables for the request, or NULL. |
453 | * @param data_size Number of bytes in @a data. | ||
454 | * @param data Payload for the join message. | 453 | * @param data Payload for the join message. |
454 | * @param data_size Number of bytes in @a data. | ||
455 | * @return Handle for the slave, NULL on error. | 455 | * @return Handle for the slave, NULL on error. |
456 | */ | 456 | */ |
457 | struct GNUNET_PSYC_Slave * | 457 | struct GNUNET_PSYC_Slave * |
@@ -466,8 +466,8 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
466 | void *cls, | 466 | void *cls, |
467 | const char *method_name, | 467 | const char *method_name, |
468 | const struct GNUNET_ENV_Environment *env, | 468 | const struct GNUNET_ENV_Environment *env, |
469 | size_t data_size, | 469 | const void *data, |
470 | const void *data); | 470 | size_t data_size); |
471 | 471 | ||
472 | 472 | ||
473 | /** | 473 | /** |
@@ -618,7 +618,6 @@ GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *channel, | |||
618 | * @param channel Channel handle. | 618 | * @param channel Channel handle. |
619 | * @param slave_key Identity of channel slave to remove. | 619 | * @param slave_key Identity of channel slave to remove. |
620 | * @param announced_at ID of the message that announced the membership change. | 620 | * @param announced_at ID of the message that announced the membership change. |
621 | * @param effective_since Removal of slave is in effect since this message ID. | ||
622 | */ | 621 | */ |
623 | void | 622 | void |
624 | GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel, | 623 | GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel, |
@@ -632,14 +631,14 @@ GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel, | |||
632 | * @param cls Closure. | 631 | * @param cls Closure. |
633 | * @param name Name of the state variable. A NULL value indicates that there | 632 | * @param name Name of the state variable. A NULL value indicates that there |
634 | * are no more state variables to be returned. | 633 | * are no more state variables to be returned. |
635 | * @param value_size Number of bytes in @a value. | ||
636 | * @param value Value of the state variable. | 634 | * @param value Value of the state variable. |
635 | * @param value_size Number of bytes in @a value. | ||
637 | */ | 636 | */ |
638 | typedef void | 637 | typedef void |
639 | (*GNUNET_PSYC_StateCallback) (void *cls, | 638 | (*GNUNET_PSYC_StateCallback) (void *cls, |
640 | const char *name, | 639 | const char *name, |
641 | size_t value_size, | 640 | const void *value, |
642 | const void *value); | 641 | size_t value_size); |
643 | 642 | ||
644 | 643 | ||
645 | /** | 644 | /** |
diff --git a/src/include/gnunet_psycstore_plugin.h b/src/include/gnunet_psycstore_plugin.h index e567de278..69d4bf7fc 100644 --- a/src/include/gnunet_psycstore_plugin.h +++ b/src/include/gnunet_psycstore_plugin.h | |||
@@ -40,7 +40,7 @@ extern "C" | |||
40 | 40 | ||
41 | 41 | ||
42 | /** | 42 | /** |
43 | * @brief struct returned by the initialization function of the plugin | 43 | * Struct returned by the initialization function of the plugin. |
44 | */ | 44 | */ |
45 | struct GNUNET_PSYCSTORE_PluginFunctions | 45 | struct GNUNET_PSYCSTORE_PluginFunctions |
46 | { | 46 | { |
@@ -59,9 +59,9 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
59 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 59 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
60 | */ | 60 | */ |
61 | int | 61 | int |
62 | (*membership_store) (void *cls, | 62 | (*membership_store) (void *cls, |
63 | const struct GNUNET_HashCode *channel_key, | 63 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
64 | const struct GNUNET_HashCode *slave_key, | 64 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
65 | int did_join, | 65 | int did_join, |
66 | uint64_t announced_at, | 66 | uint64_t announced_at, |
67 | uint64_t effective_since, | 67 | uint64_t effective_since, |
@@ -71,7 +71,7 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
71 | * Test if a member was admitted to the channel at the given message ID. | 71 | * Test if a member was admitted to the channel at the given message ID. |
72 | * | 72 | * |
73 | * @see GNUNET_PSYCSTORE_membership_test() | 73 | * @see GNUNET_PSYCSTORE_membership_test() |
74 | * | 74 | * |
75 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, | 75 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, |
76 | * #GNUNET_SYSERR if there was en error. | 76 | * #GNUNET_SYSERR if there was en error. |
77 | */ | 77 | */ |
@@ -79,41 +79,42 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
79 | (*membership_test) (void *cls, | 79 | (*membership_test) (void *cls, |
80 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 80 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
81 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | 81 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
82 | uint64_t message_id, | 82 | uint64_t message_id); |
83 | uint64_t group_generation); | ||
84 | 83 | ||
85 | /** | 84 | /** |
86 | * Store a message fragment sent to a channel. | 85 | * Store a message fragment sent to a channel. |
87 | * | 86 | * |
88 | * @see GNUNET_PSYCSTORE_fragment_store() | 87 | * @see GNUNET_PSYCSTORE_fragment_store() |
89 | * | 88 | * |
90 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 89 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
91 | */ | 90 | */ |
92 | int | 91 | int |
93 | (*fragment_store) (void *cls, | 92 | (*fragment_store) (void *cls, |
94 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 93 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
95 | const struct GNUNET_MULTICAST_MessageHeader *message); | 94 | const struct GNUNET_MULTICAST_MessageHeader *message, |
95 | uint32_t psycstore_flags); | ||
96 | 96 | ||
97 | /** | 97 | /** |
98 | * Set additional flags for a given message. | 98 | * Set additional flags for a given message. |
99 | * | 99 | * |
100 | * They are OR'd with any existing flags set. | ||
101 | * | ||
100 | * @param message_id ID of the message. | 102 | * @param message_id ID of the message. |
101 | * @param flags Flags to add. | 103 | * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags. |
102 | * | 104 | * |
103 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 105 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
104 | */ | 106 | */ |
105 | int | 107 | int |
106 | (*fragment_add_flags) (void *cls, | 108 | (*message_add_flags) (void *cls, |
107 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 109 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
108 | uint64_t message_id, | 110 | uint64_t message_id, |
109 | uint64_t multicast_flags, | 111 | uint64_t psycstore_flags); |
110 | uint64_t psyc_flags); | ||
111 | 112 | ||
112 | /** | 113 | /** |
113 | * Retrieve a message fragment by fragment ID. | 114 | * Retrieve a message fragment by fragment ID. |
114 | * | 115 | * |
115 | * @see GNUNET_PSYCSTORE_fragment_get() | 116 | * @see GNUNET_PSYCSTORE_fragment_get() |
116 | * | 117 | * |
117 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 118 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
118 | */ | 119 | */ |
119 | int | 120 | int |
@@ -127,7 +128,7 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
127 | * Retrieve all fragments of a message. | 128 | * Retrieve all fragments of a message. |
128 | * | 129 | * |
129 | * @see GNUNET_PSYCSTORE_message_get() | 130 | * @see GNUNET_PSYCSTORE_message_get() |
130 | * | 131 | * |
131 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 132 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
132 | */ | 133 | */ |
133 | int | 134 | int |
@@ -142,7 +143,7 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
142 | * offset. | 143 | * offset. |
143 | * | 144 | * |
144 | * @see GNUNET_PSYCSTORE_message_get_fragment() | 145 | * @see GNUNET_PSYCSTORE_message_get_fragment() |
145 | * | 146 | * |
146 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 147 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
147 | */ | 148 | */ |
148 | int | 149 | int |
@@ -157,7 +158,7 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
157 | * Retrieve latest values of counters for a channel master. | 158 | * Retrieve latest values of counters for a channel master. |
158 | * | 159 | * |
159 | * @see GNUNET_PSYCSTORE_counters_get_master() | 160 | * @see GNUNET_PSYCSTORE_counters_get_master() |
160 | * | 161 | * |
161 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 162 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
162 | */ | 163 | */ |
163 | int | 164 | int |
@@ -168,10 +169,10 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
168 | uint64_t *group_generation); | 169 | uint64_t *group_generation); |
169 | 170 | ||
170 | /** | 171 | /** |
171 | * Retrieve latest values of counters for a channel slave. | 172 | * Retrieve latest values of counters for a channel slave. |
172 | * | 173 | * |
173 | * @see GNUNET_PSYCSTORE_counters_get_slave() | 174 | * @see GNUNET_PSYCSTORE_counters_get_slave() |
174 | * | 175 | * |
175 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 176 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
176 | */ | 177 | */ |
177 | int | 178 | int |
@@ -183,27 +184,66 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
183 | * Set a state variable to the given value. | 184 | * Set a state variable to the given value. |
184 | * | 185 | * |
185 | * @see GNUNET_PSYCSTORE_state_modify() | 186 | * @see GNUNET_PSYCSTORE_state_modify() |
186 | * | 187 | * |
187 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 188 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
188 | */ | 189 | */ |
189 | int | 190 | int |
190 | (*state_set) (struct GNUNET_PSYCSTORE_Handle *h, | 191 | (*state_set) (void *cls, |
191 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 192 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
192 | const char *name, | 193 | const char *name, |
193 | size_t value_size, | 194 | const void *value, |
194 | const void *value); | 195 | size_t value_size); |
196 | |||
197 | |||
198 | /** | ||
199 | * Reset the state of a channel. | ||
200 | * | ||
201 | * Delete all state variables stored for the given channel. | ||
202 | * | ||
203 | * @see GNUNET_PSYCSTORE_state_reset() | ||
204 | * | ||
205 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
206 | */ | ||
207 | int | ||
208 | (*state_reset) (void *cls, | ||
209 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key); | ||
210 | |||
211 | /** | ||
212 | * Update signed state values from the current ones. | ||
213 | * | ||
214 | * Sets value_signed = value_current for each variable for the given channel. | ||
215 | */ | ||
216 | int | ||
217 | (*state_update_signed) (void *cls, | ||
218 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key); | ||
219 | |||
220 | /** | ||
221 | * Update signed values of state variables in the state store. | ||
222 | * | ||
223 | * @param h Handle for the PSYCstore. | ||
224 | * @param channel_key The channel we are interested in. | ||
225 | * @param message_id Message ID that contained the state @a hash. | ||
226 | * @param hash Hash of the serialized full state. | ||
227 | * @param rcb Callback to call with the result of the operation. | ||
228 | * @param rcb_cls Closure for the callback. | ||
229 | * | ||
230 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
231 | */ | ||
232 | int | ||
233 | (*state_hash_update) (void *cls, | ||
234 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
235 | uint64_t message_id, | ||
236 | const struct GNUNET_HashCode *hash, | ||
237 | GNUNET_PSYCSTORE_ResultCallback rcb, | ||
238 | void *rcb_cls); | ||
195 | 239 | ||
196 | /** | 240 | /** |
197 | * Retrieve a state variable by name. | 241 | * Retrieve a state variable by name (exact match). |
198 | * | 242 | * |
199 | * @param name Name of the variable to retrieve. | ||
200 | * @param[out] value_size Size of value. | ||
201 | * @param[out] value Returned value. | ||
202 | * | ||
203 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 243 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
204 | */ | 244 | */ |
205 | int | 245 | int |
206 | (*state_get) (struct GNUNET_PSYCSTORE_Handle *h, | 246 | (*state_get) (void *cls, |
207 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 247 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
208 | const char *name, | 248 | const char *name, |
209 | GNUNET_PSYCSTORE_StateCallback cb, | 249 | GNUNET_PSYCSTORE_StateCallback cb, |
@@ -213,16 +253,28 @@ struct GNUNET_PSYCSTORE_PluginFunctions | |||
213 | * Retrieve all state variables for a channel with the given prefix. | 253 | * Retrieve all state variables for a channel with the given prefix. |
214 | * | 254 | * |
215 | * @see GNUNET_PSYCSTORE_state_get_all() | 255 | * @see GNUNET_PSYCSTORE_state_get_all() |
216 | * | 256 | * |
217 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 257 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
218 | */ | 258 | */ |
219 | int | 259 | int |
220 | (*state_get_all) (struct GNUNET_PSYCSTORE_Handle *h, | 260 | (*state_get_all) (void *cls, |
221 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 261 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
222 | const char *name, | 262 | const char *name, |
223 | GNUNET_PSYCSTORE_StateCallback cb, | 263 | GNUNET_PSYCSTORE_StateCallback cb, |
224 | void *cb_cls); | 264 | void *cb_cls); |
225 | 265 | ||
266 | |||
267 | /** | ||
268 | * Retrieve all signed state variables for a channel. | ||
269 | * | ||
270 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
271 | */ | ||
272 | int | ||
273 | (*state_get_signed) (void *cls, | ||
274 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
275 | GNUNET_PSYCSTORE_StateCallback cb, | ||
276 | void *cb_cls); | ||
277 | |||
226 | }; | 278 | }; |
227 | 279 | ||
228 | 280 | ||
diff --git a/src/include/gnunet_psycstore_service.h b/src/include/gnunet_psycstore_service.h index bbf5a7d19..fab2594df 100644 --- a/src/include/gnunet_psycstore_service.h +++ b/src/include/gnunet_psycstore_service.h | |||
@@ -45,6 +45,28 @@ extern "C" | |||
45 | */ | 45 | */ |
46 | #define GNUNET_PSYCSTORE_VERSION 0x00000000 | 46 | #define GNUNET_PSYCSTORE_VERSION 0x00000000 |
47 | 47 | ||
48 | /** | ||
49 | * Flags for stored messages. | ||
50 | */ | ||
51 | enum GNUNET_PSYCSTORE_MessageFlags | ||
52 | { | ||
53 | /** | ||
54 | * The message contains state modifiers. | ||
55 | */ | ||
56 | GNUNET_PSYCSTORE_MESSAGE_STATE = 1 << 0, | ||
57 | |||
58 | /** | ||
59 | * The state modifiers have been applied to the state store. | ||
60 | */ | ||
61 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED = 1 << 1, | ||
62 | |||
63 | /** | ||
64 | * The message contains a state hash. | ||
65 | */ | ||
66 | GNUNET_PSYCSTORE_MESSAGE_STATE_HASH = 1 << 2 | ||
67 | }; | ||
68 | |||
69 | |||
48 | /** | 70 | /** |
49 | * Handle for a PSYCstore | 71 | * Handle for a PSYCstore |
50 | */ | 72 | */ |
@@ -157,6 +179,8 @@ GNUNET_PSYCSTORE_membership_test (struct GNUNET_PSYCSTORE_Handle *h, | |||
157 | * @param h Handle for the PSYCstore. | 179 | * @param h Handle for the PSYCstore. |
158 | * @param channel_key The channel the message belongs to. | 180 | * @param channel_key The channel the message belongs to. |
159 | * @param message Message to store. | 181 | * @param message Message to store. |
182 | * @param psycstore_flags Flags indicating whether the PSYC message contains | ||
183 | * state modifiers. | ||
160 | * @param rcb Callback to call with the result of the operation. | 184 | * @param rcb Callback to call with the result of the operation. |
161 | * @param rcb_cls Closure for the callback. | 185 | * @param rcb_cls Closure for the callback. |
162 | * | 186 | * |
@@ -166,6 +190,7 @@ struct GNUNET_PSYCSTORE_OperationHandle * | |||
166 | GNUNET_PSYCSTORE_fragment_store (struct GNUNET_PSYCSTORE_Handle *h, | 190 | GNUNET_PSYCSTORE_fragment_store (struct GNUNET_PSYCSTORE_Handle *h, |
167 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 191 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
168 | const struct GNUNET_MULTICAST_MessageHeader *message, | 192 | const struct GNUNET_MULTICAST_MessageHeader *message, |
193 | uint32_t psycstore_flags, | ||
169 | GNUNET_PSYCSTORE_ResultCallback rcb, | 194 | GNUNET_PSYCSTORE_ResultCallback rcb, |
170 | void *rcb_cls); | 195 | void *rcb_cls); |
171 | 196 | ||
@@ -177,12 +202,15 @@ GNUNET_PSYCSTORE_fragment_store (struct GNUNET_PSYCSTORE_Handle *h, | |||
177 | * @param cls Closure. | 202 | * @param cls Closure. |
178 | * @param message The retrieved message fragment. A NULL value indicates that | 203 | * @param message The retrieved message fragment. A NULL value indicates that |
179 | * there are no more results to be returned. | 204 | * there are no more results to be returned. |
180 | * @param flags Message flags indicating fragmentation status. | 205 | * @param flags Flags stored with the message. |
206 | * | ||
207 | * @return #GNUNET_NO to stop calling this callback with further fragments, | ||
208 | * #GNUNET_YES to continue. | ||
181 | */ | 209 | */ |
182 | typedef void | 210 | typedef int |
183 | (*GNUNET_PSYCSTORE_FragmentCallback) (void *cls, | 211 | (*GNUNET_PSYCSTORE_FragmentCallback) (void *cls, |
184 | const struct GNUNET_MULTICAST_MessageHeader *message, | 212 | struct GNUNET_MULTICAST_MessageHeader *message, |
185 | enum GNUNET_PSYC_MessageFlags flags); | 213 | enum GNUNET_PSYCSTORE_MessageFlags flags); |
186 | 214 | ||
187 | 215 | ||
188 | /** | 216 | /** |
@@ -224,7 +252,8 @@ GNUNET_PSYCSTORE_message_get (struct GNUNET_PSYCSTORE_Handle *h, | |||
224 | 252 | ||
225 | 253 | ||
226 | /** | 254 | /** |
227 | * Retrieve a fragment of message specified by its message ID and fragment offset. | 255 | * Retrieve a fragment of message specified by its message ID and fragment |
256 | * offset. | ||
228 | * | 257 | * |
229 | * @param h Handle for the PSYCstore. | 258 | * @param h Handle for the PSYCstore. |
230 | * @param channel_key The channel we are interested in. | 259 | * @param channel_key The channel we are interested in. |
@@ -267,7 +296,8 @@ typedef void | |||
267 | * @see GNUNET_PSYCSTORE_counters_get_slave() | 296 | * @see GNUNET_PSYCSTORE_counters_get_slave() |
268 | * | 297 | * |
269 | * @param cls Closure. | 298 | * @param cls Closure. |
270 | * @param max_state_msg_id Latest message ID containing state modifiers that was applied to the state store. Used for the state sync process. | 299 | * @param max_state_msg_id Latest message ID containing state modifiers that was |
300 | * applied to the state store. Used for the state sync process. | ||
271 | */ | 301 | */ |
272 | typedef void | 302 | typedef void |
273 | (*GNUNET_PSYCSTORE_SlaveCountersCallback) (void *cls, | 303 | (*GNUNET_PSYCSTORE_SlaveCountersCallback) (void *cls, |
@@ -343,6 +373,26 @@ GNUNET_PSYCSTORE_state_modify (struct GNUNET_PSYCSTORE_Handle *h, | |||
343 | 373 | ||
344 | 374 | ||
345 | /** | 375 | /** |
376 | * Reset the state of a channel. | ||
377 | * | ||
378 | * Delete all state variables stored for the given channel. | ||
379 | * | ||
380 | * @param h Handle for the PSYCstore. | ||
381 | * @param channel_key The channel we are interested in. | ||
382 | * @param rcb Callback to call with the result of the operation. | ||
383 | * @param rcb_cls Closure for the callback. | ||
384 | * | ||
385 | * @return Handle that can be used to cancel the operation. | ||
386 | */ | ||
387 | struct GNUNET_PSYCSTORE_Handle * | ||
388 | GNUNET_PSYCSTORE_state_reset (struct GNUNET_PSYCSTORE_Handle *h, | ||
389 | const struct GNUNET_CRYPTO_EccPublicKey | ||
390 | *channel_key, | ||
391 | GNUNET_PSYCSTORE_ResultCallback rcb, | ||
392 | void *rcb_cls); | ||
393 | |||
394 | |||
395 | /** | ||
346 | * Update signed values of state variables in the state store. | 396 | * Update signed values of state variables in the state store. |
347 | * | 397 | * |
348 | * @param h Handle for the PSYCstore. | 398 | * @param h Handle for the PSYCstore. |
@@ -368,15 +418,17 @@ GNUNET_PSYCSTORE_state_hash_update (struct GNUNET_PSYCSTORE_Handle *h, | |||
368 | * @param cls Closure. | 418 | * @param cls Closure. |
369 | * @param name Name of the state variable. A NULL value indicates that there are no more | 419 | * @param name Name of the state variable. A NULL value indicates that there are no more |
370 | * state variables to be returned. | 420 | * state variables to be returned. |
371 | * @param value_size Number of bytes in @a value. | ||
372 | * @param value Value of the state variable. | 421 | * @param value Value of the state variable. |
373 | t * | 422 | * @param value_size Number of bytes in @a value. |
423 | * | ||
424 | * @return #GNUNET_NO to stop calling this callback with further variables, | ||
425 | * #GNUNET_YES to continue. | ||
374 | */ | 426 | */ |
375 | typedef void | 427 | typedef int |
376 | (*GNUNET_PSYCSTORE_StateCallback) (void *cls, | 428 | (*GNUNET_PSYCSTORE_StateCallback) (void *cls, |
377 | const char *name, | 429 | const char *name, |
378 | size_t value_size, | 430 | const void *value, |
379 | const void *value); | 431 | size_t value_size); |
380 | 432 | ||
381 | 433 | ||
382 | /** | 434 | /** |
@@ -420,10 +472,10 @@ GNUNET_PSYCSTORE_state_get_all (struct GNUNET_PSYCSTORE_Handle *h, | |||
420 | /** | 472 | /** |
421 | * Cancel an operation. | 473 | * Cancel an operation. |
422 | * | 474 | * |
423 | * @param oh Handle for the operation to cancel. | 475 | * @param op Handle for the operation to cancel. |
424 | */ | 476 | */ |
425 | void | 477 | void |
426 | GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *oh); | 478 | GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op); |
427 | 479 | ||
428 | 480 | ||
429 | 481 | ||
diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h index abb749b9b..62a221de2 100644 --- a/src/include/gnunet_social_service.h +++ b/src/include/gnunet_social_service.h | |||
@@ -83,21 +83,22 @@ struct GNUNET_SOCIAL_Slicer; | |||
83 | * @param modifier_count Number of elements in the @a modifiers array. | 83 | * @param modifier_count Number of elements in the @a modifiers array. |
84 | * @param modifiers Modifiers present in the message. FIXME: use environment instead? | 84 | * @param modifiers Modifiers present in the message. FIXME: use environment instead? |
85 | * @param data_offset Byte offset of @a data in the overall data of the method. | 85 | * @param data_offset Byte offset of @a data in the overall data of the method. |
86 | * @param data_size Number of bytes in @a data. | ||
87 | * @param data Data stream given to the method (might not be zero-terminated | 86 | * @param data Data stream given to the method (might not be zero-terminated |
88 | * if data is binary). | 87 | * if data is binary). |
88 | * @param data_size Number of bytes in @a data. | ||
89 | * @param flags Message flags indicating fragmentation status. | 89 | * @param flags Message flags indicating fragmentation status. |
90 | */ | 90 | */ |
91 | typedef int (*GNUNET_SOCIAL_Method)(void *cls, | 91 | typedef int |
92 | struct GNUNET_SOCIAL_Nym *nym, | 92 | (*GNUNET_SOCIAL_Method) (void *cls, |
93 | const char *full_method_name, | 93 | struct GNUNET_SOCIAL_Nym *nym, |
94 | uint64_t message_id, | 94 | const char *full_method_name, |
95 | size_t modifier_count, | 95 | uint64_t message_id, |
96 | GNUNET_PSYC_Modifier *modifiers, | 96 | size_t modifier_count, |
97 | uint64_t data_offset, | 97 | GNUNET_PSYC_Modifier *modifiers, |
98 | size_t data_size, | 98 | uint64_t data_offset, |
99 | const void *data, | 99 | const void *data, |
100 | enum GNUNET_PSYC_MessageFlags flags); | 100 | size_t data_size, |
101 | enum GNUNET_PSYC_MessageFlags flags); | ||
101 | 102 | ||
102 | 103 | ||
103 | /** | 104 | /** |
@@ -164,16 +165,17 @@ GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer); | |||
164 | * @param method_name Method name in the entry request. | 165 | * @param method_name Method name in the entry request. |
165 | * @param variable_count Number of elements in the @a variables array. | 166 | * @param variable_count Number of elements in the @a variables array. |
166 | * @param variables Variables present in the message. | 167 | * @param variables Variables present in the message. |
167 | * @param data_size Number of bytes in @a data. | ||
168 | * @param data Payload given on enter (e.g. a password). | 168 | * @param data Payload given on enter (e.g. a password). |
169 | * @param data_size Number of bytes in @a data. | ||
169 | */ | 170 | */ |
170 | typedef void (*GNUNET_SOCIAL_AnswerDoorCallback)(void *cls, | 171 | typedef void |
171 | struct GNUNET_SOCIAL_Nym *nym, | 172 | (*GNUNET_SOCIAL_AnswerDoorCallback) (void *cls, |
172 | size_t variable_count, | 173 | struct GNUNET_SOCIAL_Nym *nym, |
173 | const char *method_name, | 174 | size_t variable_count, |
174 | GNUNET_PSYC_Modifier *variables, | 175 | const char *method_name, |
175 | size_t data_size, | 176 | GNUNET_PSYC_Modifier *variables, |
176 | const void *data); | 177 | const void *data, |
178 | size_t data_size); | ||
177 | 179 | ||
178 | 180 | ||
179 | /** | 181 | /** |
@@ -187,10 +189,11 @@ typedef void (*GNUNET_SOCIAL_AnswerDoorCallback)(void *cls, | |||
187 | * @param variable_count Number of elements in the @a variables array. | 189 | * @param variable_count Number of elements in the @a variables array. |
188 | * @param variables Variables present in the message. | 190 | * @param variables Variables present in the message. |
189 | */ | 191 | */ |
190 | typedef void (*GNUNET_SOCIAL_FarewellCallback)(void *cls, | 192 | typedef void |
191 | struct GNUNET_SOCIAL_Nym *nym, | 193 | (*GNUNET_SOCIAL_FarewellCallback) (void *cls, |
192 | size_t variable_count, | 194 | struct GNUNET_SOCIAL_Nym *nym, |
193 | GNUNET_PSYC_Modifier *variables); | 195 | size_t variable_count, |
196 | GNUNET_PSYC_Modifier *variables); | ||
194 | 197 | ||
195 | 198 | ||
196 | /** | 199 | /** |
@@ -258,16 +261,16 @@ GNUNET_SOCIAL_home_eject (struct GNUNET_SOCIAL_Home *home, | |||
258 | * @param nym Handle for the entity that wanted to enter. | 261 | * @param nym Handle for the entity that wanted to enter. |
259 | * @param method_name Method name for the rejection message. | 262 | * @param method_name Method name for the rejection message. |
260 | * @param env Environment containing variables for the message, or NULL. | 263 | * @param env Environment containing variables for the message, or NULL. |
261 | * @param data_size Number of bytes in @a data for method. | ||
262 | * @param data Data for the rejection message to send back. | 264 | * @param data Data for the rejection message to send back. |
265 | * @param data_size Number of bytes in @a data for method. | ||
263 | */ | 266 | */ |
264 | void | 267 | void |
265 | GNUNET_SOCIAL_home_reject_entry (struct GNUNET_SOCIAL_Home *home, | 268 | GNUNET_SOCIAL_home_reject_entry (struct GNUNET_SOCIAL_Home *home, |
266 | struct GNUNET_SOCIAL_Nym *nym, | 269 | struct GNUNET_SOCIAL_Nym *nym, |
267 | const char *method_name, | 270 | const char *method_name, |
268 | const struct GNUNET_ENV_Environment *env, | 271 | const struct GNUNET_ENV_Environment *env, |
269 | size_t data_size, | 272 | const void *data, |
270 | const void *data); | 273 | size_t data_size); |
271 | 274 | ||
272 | 275 | ||
273 | /** | 276 | /** |
@@ -403,8 +406,8 @@ GNUNET_SOCIAL_home_leave (struct GNUNET_SOCIAL_Home *home); | |||
403 | * pseudonym's place directly. | 406 | * pseudonym's place directly. |
404 | * @param method_name Method name for the message. | 407 | * @param method_name Method name for the message. |
405 | * @param env Environment containing variables for the message, or NULL. | 408 | * @param env Environment containing variables for the message, or NULL. |
406 | * @param data_size Number of bytes in @a data. | ||
407 | * @param data Payload for the message to give to the enter callback. | 409 | * @param data Payload for the message to give to the enter callback. |
410 | * @param data_size Number of bytes in @a data. | ||
408 | * @param slicer Slicer to use for processing incoming requests from guests. | 411 | * @param slicer Slicer to use for processing incoming requests from guests. |
409 | * @return NULL on errors, otherwise handle to the place. | 412 | * @return NULL on errors, otherwise handle to the place. |
410 | */ | 413 | */ |
@@ -414,8 +417,8 @@ GNUNET_SOCIAL_place_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
414 | char *address, | 417 | char *address, |
415 | const char *method_name, | 418 | const char *method_name, |
416 | const struct GNUNET_ENV_Environment *env, | 419 | const struct GNUNET_ENV_Environment *env, |
417 | size_t data_size, | ||
418 | const void *data, | 420 | const void *data, |
421 | size_t data_size, | ||
419 | struct GNUNET_SOCIAL_Slicer *slicer); | 422 | struct GNUNET_SOCIAL_Slicer *slicer); |
420 | 423 | ||
421 | /** | 424 | /** |
@@ -429,8 +432,8 @@ GNUNET_SOCIAL_place_enter (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
429 | * @param relays Relays for the underlying multicast group. | 432 | * @param relays Relays for the underlying multicast group. |
430 | * @param method_name Method name for the message. | 433 | * @param method_name Method name for the message. |
431 | * @param env Environment containing variables for the message, or NULL. | 434 | * @param env Environment containing variables for the message, or NULL. |
432 | * @param data_size Number of bytes in @a data. | ||
433 | * @param data Payload for the message to give to the enter callback. | 435 | * @param data Payload for the message to give to the enter callback. |
436 | * @param data_size Number of bytes in @a data. | ||
434 | * @param slicer Slicer to use for processing incoming requests from guests. | 437 | * @param slicer Slicer to use for processing incoming requests from guests. |
435 | * @return NULL on errors, otherwise handle to the place. | 438 | * @return NULL on errors, otherwise handle to the place. |
436 | */ | 439 | */ |
@@ -443,8 +446,8 @@ GNUNET_SOCIAL_place_enter2 (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
443 | struct GNUNET_PeerIdentity *relays, | 446 | struct GNUNET_PeerIdentity *relays, |
444 | const char *method_name, | 447 | const char *method_name, |
445 | const struct GNUNET_ENV_Environment *env, | 448 | const struct GNUNET_ENV_Environment *env, |
446 | size_t data_size, | ||
447 | const void *data, | 449 | const void *data, |
450 | size_t data_size, | ||
448 | struct GNUNET_SOCIAL_Slicer *slicer); | 451 | struct GNUNET_SOCIAL_Slicer *slicer); |
449 | 452 | ||
450 | 453 | ||
diff --git a/src/psycstore/Makefile.am b/src/psycstore/Makefile.am index 48f8d5ff7..6f5c7187f 100644 --- a/src/psycstore/Makefile.am +++ b/src/psycstore/Makefile.am | |||
@@ -22,7 +22,7 @@ endif | |||
22 | if HAVE_SQLITE | 22 | if HAVE_SQLITE |
23 | SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la | 23 | SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la |
24 | if HAVE_TESTING | 24 | if HAVE_TESTING |
25 | #SQLITE_TESTS = test_plugin_psycstore_sqlite | 25 | SQLITE_TESTS = test_plugin_psycstore_sqlite |
26 | endif | 26 | endif |
27 | endif | 27 | endif |
28 | 28 | ||
@@ -99,3 +99,14 @@ EXTRA_DIST = \ | |||
99 | test_psycstore.conf | 99 | test_psycstore.conf |
100 | 100 | ||
101 | 101 | ||
102 | test_plugin_psycstore_sqlite_SOURCES = \ | ||
103 | test_plugin_psycstore.c | ||
104 | test_plugin_psycstore_sqlite_LDADD = \ | ||
105 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
106 | $(top_builddir)/src/util/libgnunetutil.la | ||
107 | |||
108 | test_plugin_psycstore_postgres_SOURCES = \ | ||
109 | test_plugin_psycstore.c | ||
110 | test_plugin_psycstore_postgres_LDADD = \ | ||
111 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
112 | $(top_builddir)/src/util/libgnunetutil.la | ||
diff --git a/src/psycstore/gnunet-service-psycstore.c b/src/psycstore/gnunet-service-psycstore.c index d8f7a2690..5bc35d227 100644 --- a/src/psycstore/gnunet-service-psycstore.c +++ b/src/psycstore/gnunet-service-psycstore.c | |||
@@ -101,27 +101,72 @@ send_result_code (struct GNUNET_SERVER_Client *client, | |||
101 | uint32_t result_code, | 101 | uint32_t result_code, |
102 | const char *emsg) | 102 | const char *emsg) |
103 | { | 103 | { |
104 | struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm; | 104 | struct ResultCodeMessage *rcm; |
105 | size_t elen; | 105 | size_t elen; |
106 | 106 | ||
107 | if (NULL == emsg) | 107 | if (NULL == emsg) |
108 | elen = 0; | 108 | elen = 0; |
109 | else | 109 | else |
110 | elen = strlen (emsg) + 1; | 110 | elen = strlen (emsg) + 1; |
111 | rcm = GNUNET_malloc (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) + elen); | 111 | rcm = GNUNET_malloc (sizeof (struct ResultCodeMessage) + elen); |
112 | rcm->header.type = htons (GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE); | 112 | rcm->header.type = htons (GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE); |
113 | rcm->header.size = htons (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) + elen); | 113 | rcm->header.size = htons (sizeof (struct ResultCodeMessage) + elen); |
114 | rcm->result_code = htonl (result_code); | 114 | rcm->result_code = htonl (result_code); |
115 | memcpy (&rcm[1], emsg, elen); | 115 | memcpy (&rcm[1], emsg, elen); |
116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
117 | "Sending result %d (%s) to client\n", | 117 | "Sending result %d (%s) to client\n", |
118 | (int) result_code, | 118 | (int) result_code, |
119 | emsg); | 119 | emsg); |
120 | GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, GNUNET_NO); | 120 | GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, |
121 | GNUNET_NO); | ||
121 | GNUNET_free (rcm); | 122 | GNUNET_free (rcm); |
122 | } | 123 | } |
123 | 124 | ||
124 | 125 | ||
126 | static void | ||
127 | handle_membership_store (void *cls, | ||
128 | struct GNUNET_SERVER_Client *client, | ||
129 | const struct GNUNET_MessageHeader *message) | ||
130 | { | ||
131 | const struct MembershipStoreMessage *msg = | ||
132 | (const struct MembershipStoreMessage *) message; | ||
133 | |||
134 | int res = db->membership_store (db->cls, msg->channel_key, msg->slave_key, | ||
135 | msg->did_join, msg->announced_at, | ||
136 | msg->effective_since, msg->group_generation); | ||
137 | |||
138 | if (res != GNUNET_OK) | ||
139 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
140 | _("Failed to store membership information!\n")); | ||
141 | |||
142 | send_result_code (client, res, NULL); | ||
143 | } | ||
144 | |||
145 | |||
146 | static void | ||
147 | handle_membership_test (void *cls, | ||
148 | struct GNUNET_SERVER_Client *client, | ||
149 | const struct GNUNET_MessageHeader *message) | ||
150 | { | ||
151 | const struct MembershipTestMessage *msg = | ||
152 | (const struct MembershipTestMessage *) message; | ||
153 | |||
154 | int res = db->membership_test (db->cls, msg->channel_key, msg->slave_key, | ||
155 | msg->message_id); | ||
156 | switch (res) | ||
157 | { | ||
158 | case GNUNET_YES: | ||
159 | case GNUNET_NO: | ||
160 | break; | ||
161 | default: | ||
162 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
163 | _("Failed to test membership!\n")); | ||
164 | } | ||
165 | |||
166 | send_result_code (client, res, NULL); | ||
167 | } | ||
168 | |||
169 | |||
125 | /** | 170 | /** |
126 | * Handle PSYCstore clients. | 171 | * Handle PSYCstore clients. |
127 | * | 172 | * |
@@ -135,6 +180,12 @@ run (void *cls, | |||
135 | const struct GNUNET_CONFIGURATION_Handle *c) | 180 | const struct GNUNET_CONFIGURATION_Handle *c) |
136 | { | 181 | { |
137 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 182 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
183 | {&handle_membership_store, NULL, | ||
184 | GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_STORE, | ||
185 | sizeof (struct MembershipStoreMessage)}, | ||
186 | {&handle_membership_test, NULL, | ||
187 | GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_TEST, | ||
188 | sizeof (struct MembershipTestMessage)}, | ||
138 | {NULL, NULL, 0, 0} | 189 | {NULL, NULL, 0, 0} |
139 | }; | 190 | }; |
140 | 191 | ||
diff --git a/src/psycstore/plugin_psycstore_sqlite.c b/src/psycstore/plugin_psycstore_sqlite.c index 8bec31f12..f214e1c60 100644 --- a/src/psycstore/plugin_psycstore_sqlite.c +++ b/src/psycstore/plugin_psycstore_sqlite.c | |||
@@ -25,9 +25,16 @@ t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* | ||
29 | * FIXME: SQLite3 only supports signed 64-bit integers natively, | ||
30 | * thus it can only store 63 bits of the uint64_t's. | ||
31 | */ | ||
32 | |||
28 | #include "platform.h" | 33 | #include "platform.h" |
29 | #include "gnunet_psycstore_plugin.h" | 34 | #include "gnunet_psycstore_plugin.h" |
30 | #include "gnunet_psycstore_service.h" | 35 | #include "gnunet_psycstore_service.h" |
36 | #include "gnunet_multicast_service.h" | ||
37 | #include "gnunet_crypto_lib.h" | ||
31 | #include "psycstore.h" | 38 | #include "psycstore.h" |
32 | #include <sqlite3.h> | 39 | #include <sqlite3.h> |
33 | 40 | ||
@@ -43,13 +50,14 @@ t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
43 | */ | 50 | */ |
44 | #define BUSY_TIMEOUT_MS 1000 | 51 | #define BUSY_TIMEOUT_MS 1000 |
45 | 52 | ||
53 | #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING | ||
46 | 54 | ||
47 | /** | 55 | /** |
48 | * Log an error message at log-level 'level' that indicates | 56 | * Log an error message at log-level 'level' that indicates |
49 | * a failure of the command 'cmd' on file 'filename' | 57 | * a failure of the command 'cmd' on file 'filename' |
50 | * with the message given by strerror(errno). | 58 | * with the message given by strerror(errno). |
51 | */ | 59 | */ |
52 | #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "psycstore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0) | 60 | #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "psycstore-sqlite", _("`%s' failed at %s:%d with error: %s (%d)\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh), sqlite3_errcode(db->dbh)); } while(0) |
53 | 61 | ||
54 | #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__) | 62 | #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__) |
55 | 63 | ||
@@ -100,9 +108,9 @@ struct Plugin | |||
100 | sqlite3_stmt *insert_fragment; | 108 | sqlite3_stmt *insert_fragment; |
101 | 109 | ||
102 | /** | 110 | /** |
103 | * Precompiled SQL for fragment_add_flags() | 111 | * Precompiled SQL for message_add_flags() |
104 | */ | 112 | */ |
105 | sqlite3_stmt *update_fragment_flags; | 113 | sqlite3_stmt *update_message_flags; |
106 | 114 | ||
107 | /** | 115 | /** |
108 | * Precompiled SQL for fragment_get() | 116 | * Precompiled SQL for fragment_get() |
@@ -122,12 +130,12 @@ struct Plugin | |||
122 | /** | 130 | /** |
123 | * Precompiled SQL for counters_get_master() | 131 | * Precompiled SQL for counters_get_master() |
124 | */ | 132 | */ |
125 | sqlite3_stmt *select_master_counters; | 133 | sqlite3_stmt *select_counters_master; |
126 | 134 | ||
127 | /** | 135 | /** |
128 | * Precompiled SQL for counters_get_slave() | 136 | * Precompiled SQL for counters_get_slave() |
129 | */ | 137 | */ |
130 | sqlite3_stmt *select_slave_counters; | 138 | sqlite3_stmt *select_counters_slave; |
131 | 139 | ||
132 | 140 | ||
133 | /** | 141 | /** |
@@ -136,11 +144,6 @@ struct Plugin | |||
136 | sqlite3_stmt *insert_state_current; | 144 | sqlite3_stmt *insert_state_current; |
137 | 145 | ||
138 | /** | 146 | /** |
139 | * Precompiled SQL for state_set() | ||
140 | */ | ||
141 | sqlite3_stmt *update_state_current; | ||
142 | |||
143 | /** | ||
144 | * Precompiled SQL for state_set_signed() | 147 | * Precompiled SQL for state_set_signed() |
145 | */ | 148 | */ |
146 | sqlite3_stmt *update_state_signed; | 149 | sqlite3_stmt *update_state_signed; |
@@ -166,6 +169,11 @@ struct Plugin | |||
166 | sqlite3_stmt *delete_state_sync; | 169 | sqlite3_stmt *delete_state_sync; |
167 | 170 | ||
168 | /** | 171 | /** |
172 | * Precompiled SQL for state_get_signed() | ||
173 | */ | ||
174 | sqlite3_stmt *select_state_signed; | ||
175 | |||
176 | /** | ||
169 | * Precompiled SQL for state_get() | 177 | * Precompiled SQL for state_get() |
170 | */ | 178 | */ |
171 | sqlite3_stmt *select_state_one; | 179 | sqlite3_stmt *select_state_one; |
@@ -177,6 +185,15 @@ struct Plugin | |||
177 | 185 | ||
178 | }; | 186 | }; |
179 | 187 | ||
188 | #if DEBUG_PSYCSTORE | ||
189 | |||
190 | static void | ||
191 | sql_trace (void *cls, const char *sql) | ||
192 | { | ||
193 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SQL query:\n%s\n", sql); | ||
194 | } | ||
195 | |||
196 | #endif | ||
180 | 197 | ||
181 | /** | 198 | /** |
182 | * @brief Prepare a SQL statement | 199 | * @brief Prepare a SQL statement |
@@ -208,8 +225,7 @@ sql_prepare (sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt) | |||
208 | * @brief Prepare a SQL statement | 225 | * @brief Prepare a SQL statement |
209 | * | 226 | * |
210 | * @param dbh handle to the database | 227 | * @param dbh handle to the database |
211 | * @param zSql SQL statement, UTF-8 encoded | 228 | * @param sql SQL statement, UTF-8 encoded |
212 | * @param ppStmt set to the prepared statement | ||
213 | * @return 0 on success | 229 | * @return 0 on success |
214 | */ | 230 | */ |
215 | static int | 231 | static int |
@@ -262,7 +278,7 @@ database_setup (struct Plugin *plugin) | |||
262 | plugin->fn = filename; | 278 | plugin->fn = filename; |
263 | 279 | ||
264 | /* Open database and precompile statements */ | 280 | /* Open database and precompile statements */ |
265 | if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) | 281 | if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh)) |
266 | { | 282 | { |
267 | LOG (GNUNET_ERROR_TYPE_ERROR, | 283 | LOG (GNUNET_ERROR_TYPE_ERROR, |
268 | _("Unable to initialize SQLite: %s.\n"), | 284 | _("Unable to initialize SQLite: %s.\n"), |
@@ -270,6 +286,10 @@ database_setup (struct Plugin *plugin) | |||
270 | return GNUNET_SYSERR; | 286 | return GNUNET_SYSERR; |
271 | } | 287 | } |
272 | 288 | ||
289 | #if DEBUG_PSYCSTORE | ||
290 | sqlite3_trace (plugin->dbh, &sql_trace, NULL); | ||
291 | #endif | ||
292 | |||
273 | sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); | 293 | sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); |
274 | sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL"); | 294 | sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL"); |
275 | sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); | 295 | sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); |
@@ -284,62 +304,62 @@ database_setup (struct Plugin *plugin) | |||
284 | /* Create tables */ | 304 | /* Create tables */ |
285 | 305 | ||
286 | sql_exec (plugin->dbh, | 306 | sql_exec (plugin->dbh, |
287 | "CREATE TABLE IF NOT EXISTS channels (" | 307 | "CREATE TABLE IF NOT EXISTS channels (\n" |
288 | " id INTEGER PRIMARY KEY," | 308 | " id INTEGER PRIMARY KEY,\n" |
289 | " pub_key BLOB UNIQUE" | 309 | " pub_key BLOB UNIQUE\n" |
290 | ");"); | 310 | ");"); |
291 | 311 | ||
292 | sql_exec (plugin->dbh, | 312 | sql_exec (plugin->dbh, |
293 | "CREATE TABLE IF NOT EXISTS slaves (" | 313 | "CREATE TABLE IF NOT EXISTS slaves (\n" |
294 | " id INTEGER PRIMARY KEY," | 314 | " id INTEGER PRIMARY KEY,\n" |
295 | " pub_key BLOB UNIQUE" | 315 | " pub_key BLOB UNIQUE\n" |
296 | ");"); | 316 | ");"); |
297 | 317 | ||
298 | sql_exec (plugin->dbh, | 318 | sql_exec (plugin->dbh, |
299 | "CREATE TABLE IF NOT EXISTS membership (" | 319 | "CREATE TABLE IF NOT EXISTS membership (\n" |
300 | " channel_id INTEGER NOT NULL REFERENCES channels(id)," | 320 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
301 | " slave_id INTEGER NOT NULL REFERENCES slaves(id)," | 321 | " slave_id INTEGER NOT NULL REFERENCES slaves(id),\n" |
302 | " did_join INTEGER NOT NULL," | 322 | " did_join INTEGER NOT NULL,\n" |
303 | " announced_at INTEGER NOT NULL," | 323 | " announced_at INTEGER NOT NULL,\n" |
304 | " effective_since INTEGER NOT NULL," | 324 | " effective_since INTEGER NOT NULL,\n" |
305 | " group_generation INTEGER NOT NULL" | 325 | " group_generation INTEGER NOT NULL\n" |
306 | ");"); | 326 | ");"); |
307 | sql_exec (plugin->dbh, | 327 | sql_exec (plugin->dbh, |
308 | "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id " | 328 | "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id " |
309 | "ON membership (channel_id, slave_id);"); | 329 | "ON membership (channel_id, slave_id);"); |
310 | 330 | ||
311 | sql_exec (plugin->dbh, | 331 | sql_exec (plugin->dbh, |
312 | "CREATE TABLE IF NOT EXISTS messages (" | 332 | "CREATE TABLE IF NOT EXISTS messages (\n" |
313 | " channel_id INTEGER NOT NULL," | 333 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
314 | " hop_counter INTEGER NOT NULL," | 334 | " hop_counter INTEGER NOT NULL,\n" |
315 | " signature BLOB," | 335 | " signature BLOB,\n" |
316 | " purpose BLOB," | 336 | " purpose BLOB,\n" |
317 | " fragment_id INTEGER NOT NULL," | 337 | " fragment_id INTEGER NOT NULL,\n" |
318 | " fragment_offset INTEGER NOT NULL," | 338 | " fragment_offset INTEGER NOT NULL,\n" |
319 | " message_id INTEGER NOT NULL," | 339 | " message_id INTEGER NOT NULL,\n" |
320 | " group_generation INTEGER NOT NULL," | 340 | " group_generation INTEGER NOT NULL,\n" |
321 | " multicast_flags INTEGER NOT NULL," | 341 | " multicast_flags INTEGER NOT NULL,\n" |
322 | " psyc_flags INTEGER NOT NULL," | 342 | " psycstore_flags INTEGER NOT NULL,\n" |
323 | " data BLOB," | 343 | " data BLOB,\n" |
324 | " PRIMARY KEY (channel_id, fragment_id)," | 344 | " PRIMARY KEY (channel_id, fragment_id),\n" |
325 | " UNIQUE (channel_id, message_id, fragment_offset)" | 345 | " UNIQUE (channel_id, message_id, fragment_offset)\n" |
326 | ");"); | 346 | ");"); |
327 | 347 | ||
328 | sql_exec (plugin->dbh, | 348 | sql_exec (plugin->dbh, |
329 | "CREATE TABLE IF NOT EXISTS state (" | 349 | "CREATE TABLE IF NOT EXISTS state (\n" |
330 | " channel_id INTEGER NOT NULL," | 350 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
331 | " name TEXT NOT NULL," | 351 | " name TEXT NOT NULL,\n" |
332 | " value_current BLOB, " | 352 | " value_current BLOB,\n" |
333 | " value_signed BLOB, " | 353 | " value_signed BLOB,\n" |
334 | " PRIMARY KEY (channel_id, name)" | 354 | " PRIMARY KEY (channel_id, name)\n" |
335 | ");"); | 355 | ");"); |
336 | 356 | ||
337 | sql_exec (plugin->dbh, | 357 | sql_exec (plugin->dbh, |
338 | "CREATE TABLE IF NOT EXISTS state_sync (" | 358 | "CREATE TABLE IF NOT EXISTS state_sync (\n" |
339 | " channel_id INTEGER NOT NULL," | 359 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
340 | " name TEXT NOT NULL," | 360 | " name TEXT NOT NULL,\n" |
341 | " value BLOB, " | 361 | " value BLOB,\n" |
342 | " PRIMARY KEY (channel_id, name)" | 362 | " PRIMARY KEY (channel_id, name)\n" |
343 | ");"); | 363 | ");"); |
344 | 364 | ||
345 | /* Prepare statements */ | 365 | /* Prepare statements */ |
@@ -353,132 +373,143 @@ database_setup (struct Plugin *plugin) | |||
353 | &plugin->insert_slave_key); | 373 | &plugin->insert_slave_key); |
354 | 374 | ||
355 | sql_prepare (plugin->dbh, | 375 | sql_prepare (plugin->dbh, |
356 | "INSERT INTO membership " | 376 | "INSERT INTO membership\n" |
357 | " (channel_id, slave_id, did_join, announced_at, " | 377 | " (channel_id, slave_id, did_join, announced_at,\n" |
358 | " effective_since, group_generation) " | 378 | " effective_since, group_generation)\n" |
359 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), " | 379 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n" |
360 | " (SELECT id FROM slaves WHERE pub_key = ?), " | 380 | " (SELECT id FROM slaves WHERE pub_key = ?),\n" |
361 | " ?, ?, ?, ?);", | 381 | " ?, ?, ?, ?);", |
362 | &plugin->insert_membership); | 382 | &plugin->insert_membership); |
363 | 383 | ||
364 | sql_prepare (plugin->dbh, | 384 | sql_prepare (plugin->dbh, |
365 | "SELECT did_join FROM membership " | 385 | "SELECT did_join FROM membership\n" |
366 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 386 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
367 | " AND slave_id = ? AND effective_since <= ? " | 387 | " AND slave_id = (SELECT id FROM slaves WHERE pub_key = ?)\n" |
388 | " AND effective_since <= ? AND did_join = 1\n" | ||
368 | "ORDER BY announced_at DESC LIMIT 1;", | 389 | "ORDER BY announced_at DESC LIMIT 1;", |
369 | &plugin->select_membership); | 390 | &plugin->select_membership); |
370 | 391 | ||
371 | sql_prepare (plugin->dbh, | 392 | sql_prepare (plugin->dbh, |
372 | "INSERT INTO messages " | 393 | "INSERT INTO messages\n" |
373 | " (channel_id, hop_counter, signature, purpose, " | 394 | " (channel_id, hop_counter, signature, purpose,\n" |
374 | " fragment_id, fragment_offset, message_id, " | 395 | " fragment_id, fragment_offset, message_id,\n" |
375 | " group_generation, multicast_flags, psyc_flags, data) " | 396 | " group_generation, multicast_flags, psycstore_flags, data)\n" |
376 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), " | 397 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n" |
377 | " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", | 398 | " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", |
378 | &plugin->insert_fragment); | 399 | &plugin->insert_fragment); |
379 | 400 | ||
380 | sql_prepare (plugin->dbh, | 401 | sql_prepare (plugin->dbh, |
381 | "UPDATE messages " | 402 | "UPDATE messages\n" |
382 | "SET multicast_flags = multicast_flags | ?, " | 403 | "SET psycstore_flags = psycstore_flags | ?\n" |
383 | " psyc_flags = psyc_flags | ? " | 404 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
384 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 405 | " AND message_id = ? AND fragment_offset = 0;", |
385 | " AND message_id = ?;", | 406 | &plugin->update_message_flags); |
386 | &plugin->update_fragment_flags); | ||
387 | 407 | ||
388 | sql_prepare (plugin->dbh, | 408 | sql_prepare (plugin->dbh, |
389 | "SELECT hop_counter, signature, purpose, " | 409 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
390 | " fragment_offset, message_id, group_generation, " | 410 | " fragment_offset, message_id, group_generation,\n" |
391 | " multicast_flags, psyc_flags, data " | 411 | " multicast_flags, psycstore_flags, data\n" |
392 | "FROM messages " | 412 | "FROM messages\n" |
393 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 413 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
394 | " AND fragment_id = ?;", | 414 | " AND fragment_id = ?;", |
395 | &plugin->select_fragment); | 415 | &plugin->select_fragment); |
396 | 416 | ||
397 | sql_prepare (plugin->dbh, | 417 | sql_prepare (plugin->dbh, |
398 | "SELECT hop_counter, signature, purpose, " | 418 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
399 | " fragment_id, fragment_offset, group_generation, " | 419 | " fragment_offset, message_id, group_generation,\n" |
400 | " multicast_flags, psyc_flags, data " | 420 | " multicast_flags, psycstore_flags, data\n" |
401 | "FROM messages " | 421 | "FROM messages\n" |
402 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 422 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
403 | " AND message_id = ?;", | 423 | " AND message_id = ?;", |
404 | &plugin->select_message); | 424 | &plugin->select_message); |
405 | 425 | ||
406 | sql_prepare (plugin->dbh, | 426 | sql_prepare (plugin->dbh, |
407 | "SELECT hop_counter, signature, purpose, " | 427 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
408 | " fragment_id, message_id, group_generation, " | 428 | " fragment_offset, message_id, group_generation,\n" |
409 | " multicast_flags, psyc_flags, data " | 429 | " multicast_flags, psycstore_flags, data\n" |
410 | "FROM messages " | 430 | "FROM messages\n" |
411 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 431 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
412 | " AND message_id = ? AND fragment_offset = ?;", | 432 | " AND message_id = ? AND fragment_offset = ?;", |
413 | &plugin->select_message_fragment); | 433 | &plugin->select_message_fragment); |
414 | 434 | ||
415 | sql_prepare (plugin->dbh, | 435 | sql_prepare (plugin->dbh, |
416 | "SELECT max(fragment_id), max(message_id), max(group_generation) " | 436 | "SELECT fragment_id, message_id, group_generation\n" |
417 | "FROM messages " | 437 | "FROM messages\n" |
418 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 438 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
419 | &plugin->select_master_counters); | 439 | "ORDER BY fragment_id DESC LIMIT 1;", |
440 | &plugin->select_counters_master); | ||
420 | 441 | ||
421 | sql_prepare (plugin->dbh, | 442 | sql_prepare (plugin->dbh, |
422 | "SELECT max(message_id) " | 443 | "SELECT message_id\n" |
423 | "FROM messages " | 444 | "FROM messages\n" |
424 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 445 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
425 | " AND psyc_flags & ?;", | 446 | " AND psycstore_flags & ?\n" |
426 | &plugin->select_slave_counters); | 447 | "ORDER BY message_id DESC LIMIT 1", |
448 | &plugin->select_counters_slave); | ||
427 | 449 | ||
428 | sql_prepare (plugin->dbh, | 450 | sql_prepare (plugin->dbh, |
429 | "INSERT OR REPLACE INTO state (channel_id, name, value_current) " | 451 | "INSERT OR REPLACE INTO state\n" |
430 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", | 452 | " (channel_id, name, value_current, value_signed)\n" |
453 | "SELECT new.channel_id, new.name,\n" | ||
454 | " new.value_current, old.value_signed\n" | ||
455 | "FROM (SELECT (SELECT id FROM channels WHERE pub_key = ?)\n" | ||
456 | " AS channel_id,\n" | ||
457 | " ? AS name, ? AS value_current) AS new\n" | ||
458 | "LEFT JOIN (SELECT channel_id, name, value_signed\n" | ||
459 | " FROM state) AS old\n" | ||
460 | "ON new.channel_id = old.channel_id AND new.name = old.name;", | ||
431 | &plugin->insert_state_current); | 461 | &plugin->insert_state_current); |
432 | 462 | ||
433 | sql_prepare (plugin->dbh, | 463 | sql_prepare (plugin->dbh, |
434 | "UPDATE state " | 464 | "UPDATE state\n" |
435 | "SET value_current = ? " | 465 | "SET value_signed = value_current\n" |
436 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 466 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
437 | " AND name = ?;", | ||
438 | &plugin->update_state_current); | ||
439 | |||
440 | sql_prepare (plugin->dbh, | ||
441 | "UPDATE state " | ||
442 | "SET value_signed = value_current " | ||
443 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) ", | ||
444 | &plugin->update_state_signed); | 467 | &plugin->update_state_signed); |
445 | 468 | ||
446 | sql_prepare (plugin->dbh, | 469 | sql_prepare (plugin->dbh, |
447 | "INSERT INTO state_sync (channel_id, name, value) " | 470 | "INSERT INTO state_sync (channel_id, name, value)\n" |
448 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", | 471 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", |
449 | &plugin->insert_state_sync); | 472 | &plugin->insert_state_sync); |
450 | 473 | ||
451 | sql_prepare (plugin->dbh, | 474 | sql_prepare (plugin->dbh, |
452 | "DELETE FROM state " | 475 | "DELETE FROM state\n" |
453 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 476 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
454 | &plugin->delete_state); | 477 | &plugin->delete_state); |
455 | 478 | ||
456 | sql_prepare (plugin->dbh, | 479 | sql_prepare (plugin->dbh, |
457 | "INSERT INTO state " | 480 | "INSERT INTO state\n" |
458 | " (channel_id, name, value_current, value_signed) " | 481 | " (channel_id, name, value_current, value_signed)\n" |
459 | "SELECT channel_id, name, value, value " | 482 | "SELECT channel_id, name, value, value\n" |
460 | "FROM state_sync " | 483 | "FROM state_sync\n" |
461 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 484 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
462 | &plugin->insert_state_from_sync); | 485 | &plugin->insert_state_from_sync); |
463 | 486 | ||
464 | sql_prepare (plugin->dbh, | 487 | sql_prepare (plugin->dbh, |
465 | "DELETE FROM state_sync " | 488 | "DELETE FROM state_sync\n" |
466 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 489 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
467 | &plugin->delete_state_sync); | 490 | &plugin->delete_state_sync); |
468 | 491 | ||
469 | sql_prepare (plugin->dbh, | 492 | sql_prepare (plugin->dbh, |
470 | "SELECT value_current " | 493 | "SELECT value_current\n" |
471 | "FROM state " | 494 | "FROM state\n" |
472 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 495 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
473 | " AND name = ?;", | 496 | " AND name = ?;", |
474 | &plugin->select_state_one); | 497 | &plugin->select_state_one); |
475 | 498 | ||
476 | sql_prepare (plugin->dbh, | 499 | sql_prepare (plugin->dbh, |
477 | "SELECT value_current " | 500 | "SELECT name, value_current\n" |
478 | "FROM state " | 501 | "FROM state\n" |
479 | "WHERE name LIKE ? OR name LIKE ?;", | 502 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
503 | " AND name = ? OR name LIKE ?;", | ||
480 | &plugin->select_state_prefix); | 504 | &plugin->select_state_prefix); |
481 | 505 | ||
506 | sql_prepare (plugin->dbh, | ||
507 | "SELECT name, value_signed\n" | ||
508 | "FROM state\n" | ||
509 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)" | ||
510 | " AND value_signed IS NOT NULL;", | ||
511 | &plugin->select_state_signed); | ||
512 | |||
482 | return GNUNET_OK; | 513 | return GNUNET_OK; |
483 | } | 514 | } |
484 | 515 | ||
@@ -509,8 +540,8 @@ database_shutdown (struct Plugin *plugin) | |||
509 | if (NULL != plugin->insert_fragment) | 540 | if (NULL != plugin->insert_fragment) |
510 | sqlite3_finalize (plugin->insert_fragment); | 541 | sqlite3_finalize (plugin->insert_fragment); |
511 | 542 | ||
512 | if (NULL != plugin->update_fragment_flags) | 543 | if (NULL != plugin->update_message_flags) |
513 | sqlite3_finalize (plugin->update_fragment_flags); | 544 | sqlite3_finalize (plugin->update_message_flags); |
514 | 545 | ||
515 | if (NULL != plugin->select_fragment) | 546 | if (NULL != plugin->select_fragment) |
516 | sqlite3_finalize (plugin->select_fragment); | 547 | sqlite3_finalize (plugin->select_fragment); |
@@ -521,18 +552,15 @@ database_shutdown (struct Plugin *plugin) | |||
521 | if (NULL != plugin->select_message_fragment) | 552 | if (NULL != plugin->select_message_fragment) |
522 | sqlite3_finalize (plugin->select_message_fragment); | 553 | sqlite3_finalize (plugin->select_message_fragment); |
523 | 554 | ||
524 | if (NULL != plugin->select_master_counters) | 555 | if (NULL != plugin->select_counters_master) |
525 | sqlite3_finalize (plugin->select_master_counters); | 556 | sqlite3_finalize (plugin->select_counters_master); |
526 | 557 | ||
527 | if (NULL != plugin->select_slave_counters) | 558 | if (NULL != plugin->select_counters_slave) |
528 | sqlite3_finalize (plugin->select_slave_counters); | 559 | sqlite3_finalize (plugin->select_counters_slave); |
529 | 560 | ||
530 | if (NULL != plugin->insert_state_current) | 561 | if (NULL != plugin->insert_state_current) |
531 | sqlite3_finalize (plugin->insert_state_current); | 562 | sqlite3_finalize (plugin->insert_state_current); |
532 | 563 | ||
533 | if (NULL != plugin->update_state_current) | ||
534 | sqlite3_finalize (plugin->update_state_current); | ||
535 | |||
536 | if (NULL != plugin->update_state_signed) | 564 | if (NULL != plugin->update_state_signed) |
537 | sqlite3_finalize (plugin->update_state_signed); | 565 | sqlite3_finalize (plugin->update_state_signed); |
538 | 566 | ||
@@ -579,6 +607,65 @@ database_shutdown (struct Plugin *plugin) | |||
579 | } | 607 | } |
580 | 608 | ||
581 | 609 | ||
610 | static int | ||
611 | channel_key_store (struct Plugin *plugin, | ||
612 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
613 | { | ||
614 | sqlite3_stmt *stmt = plugin->insert_channel_key; | ||
615 | |||
616 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
617 | sizeof (*channel_key), SQLITE_STATIC)) | ||
618 | { | ||
619 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
620 | "insert_channel_key (bind)"); | ||
621 | } | ||
622 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
623 | { | ||
624 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
625 | "insert_channel_key (step)"); | ||
626 | } | ||
627 | |||
628 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
629 | { | ||
630 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
631 | "insert_channel_key (reset)"); | ||
632 | return GNUNET_SYSERR; | ||
633 | } | ||
634 | |||
635 | return GNUNET_OK; | ||
636 | } | ||
637 | |||
638 | |||
639 | static int | ||
640 | slave_key_store (struct Plugin *plugin, | ||
641 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key) | ||
642 | { | ||
643 | sqlite3_stmt *stmt = plugin->insert_slave_key; | ||
644 | |||
645 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, slave_key, | ||
646 | sizeof (*slave_key), SQLITE_STATIC)) | ||
647 | { | ||
648 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
649 | "insert_slave_key (bind)"); | ||
650 | } | ||
651 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
652 | { | ||
653 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
654 | "insert_slave_key (step)"); | ||
655 | } | ||
656 | |||
657 | |||
658 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
659 | { | ||
660 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
661 | "insert_slave_key (reset)"); | ||
662 | return GNUNET_SYSERR; | ||
663 | } | ||
664 | |||
665 | return GNUNET_OK; | ||
666 | } | ||
667 | |||
668 | |||
582 | /** | 669 | /** |
583 | * Store join/leave events for a PSYC channel in order to be able to answer | 670 | * Store join/leave events for a PSYC channel in order to be able to answer |
584 | * membership test queries later. | 671 | * membership test queries later. |
@@ -587,17 +674,56 @@ database_shutdown (struct Plugin *plugin) | |||
587 | * | 674 | * |
588 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 675 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
589 | */ | 676 | */ |
590 | int | 677 | static int |
591 | libgnunet_plugin_psycstore_sqlite_membership_store | 678 | membership_store (void *cls, |
592 | (void *cls, | 679 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
593 | const struct GNUNET_HashCode *channel_key, | 680 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
594 | const struct GNUNET_HashCode *slave_key, | 681 | int did_join, |
595 | int did_join, | 682 | uint64_t announced_at, |
596 | uint64_t announced_at, | 683 | uint64_t effective_since, |
597 | uint64_t effective_since, | 684 | uint64_t group_generation) |
598 | uint64_t group_generation) { | 685 | { |
686 | if (announced_at > INT64_MAX || | ||
687 | effective_since > INT64_MAX || | ||
688 | group_generation > INT64_MAX) | ||
689 | { | ||
690 | GNUNET_break (0); | ||
691 | return GNUNET_SYSERR; | ||
692 | } | ||
693 | |||
694 | struct Plugin *plugin = cls; | ||
695 | sqlite3_stmt *stmt = plugin->insert_membership; | ||
599 | 696 | ||
697 | if (GNUNET_OK != channel_key_store (plugin, channel_key) || | ||
698 | GNUNET_OK != slave_key_store (plugin, slave_key)) | ||
699 | return GNUNET_SYSERR; | ||
600 | 700 | ||
701 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
702 | sizeof (*channel_key), SQLITE_STATIC) || | ||
703 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key, | ||
704 | sizeof (*slave_key), SQLITE_STATIC) || | ||
705 | SQLITE_OK != sqlite3_bind_int (stmt, 3, did_join) || | ||
706 | SQLITE_OK != sqlite3_bind_int64 (stmt, 4, announced_at) || | ||
707 | SQLITE_OK != sqlite3_bind_int64 (stmt, 5, effective_since) || | ||
708 | SQLITE_OK != sqlite3_bind_int64 (stmt, 6, group_generation)) | ||
709 | { | ||
710 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
711 | "insert_membership (bind)"); | ||
712 | } | ||
713 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
714 | { | ||
715 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
716 | "insert_membership (step)"); | ||
717 | } | ||
718 | |||
719 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
720 | { | ||
721 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
722 | "insert_membership (reset)"); | ||
723 | return GNUNET_SYSERR; | ||
724 | } | ||
725 | |||
726 | return GNUNET_OK; | ||
601 | } | 727 | } |
602 | 728 | ||
603 | /** | 729 | /** |
@@ -608,14 +734,44 @@ libgnunet_plugin_psycstore_sqlite_membership_store | |||
608 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, | 734 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, |
609 | * #GNUNET_SYSERR if there was en error. | 735 | * #GNUNET_SYSERR if there was en error. |
610 | */ | 736 | */ |
611 | int | 737 | static int |
612 | libgnunet_plugin_psycstore_sqlite_membership_test | 738 | membership_test (void *cls, |
613 | (void *cls, | 739 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
614 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 740 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
615 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | 741 | uint64_t message_id) |
616 | uint64_t message_id, | 742 | { |
617 | uint64_t group_generation) { | 743 | struct Plugin *plugin = cls; |
744 | sqlite3_stmt *stmt = plugin->select_membership; | ||
745 | int ret = GNUNET_SYSERR; | ||
746 | |||
747 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
748 | sizeof (*channel_key), SQLITE_STATIC) || | ||
749 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key, | ||
750 | sizeof (*slave_key), SQLITE_STATIC) || | ||
751 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id)) | ||
752 | { | ||
753 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
754 | "select_membership (bind)"); | ||
755 | } | ||
756 | else | ||
757 | { | ||
758 | switch (sqlite3_step (stmt)) | ||
759 | { | ||
760 | case SQLITE_DONE: | ||
761 | ret = GNUNET_NO; | ||
762 | break; | ||
763 | case SQLITE_ROW: | ||
764 | ret = GNUNET_YES; | ||
765 | } | ||
766 | } | ||
618 | 767 | ||
768 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
769 | { | ||
770 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
771 | "select_membership (reset)"); | ||
772 | } | ||
773 | |||
774 | return ret; | ||
619 | } | 775 | } |
620 | 776 | ||
621 | /** | 777 | /** |
@@ -625,30 +781,141 @@ libgnunet_plugin_psycstore_sqlite_membership_test | |||
625 | * | 781 | * |
626 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 782 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
627 | */ | 783 | */ |
628 | int | 784 | static int |
629 | libgnunet_plugin_psycstore_sqlite_fragment_store | 785 | fragment_store (void *cls, |
630 | (void *cls, | 786 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
631 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 787 | const struct GNUNET_MULTICAST_MessageHeader *msg, |
632 | const struct GNUNET_MULTICAST_MessageHeader *message) { | 788 | uint32_t psycstore_flags) |
789 | { | ||
790 | if (msg->fragment_id > INT64_MAX || | ||
791 | msg->fragment_offset > INT64_MAX || | ||
792 | msg->message_id > INT64_MAX || | ||
793 | msg->group_generation > INT64_MAX) | ||
794 | { | ||
795 | GNUNET_break (0); | ||
796 | return GNUNET_SYSERR; | ||
797 | } | ||
798 | |||
799 | struct Plugin *plugin = cls; | ||
800 | sqlite3_stmt *stmt = plugin->insert_fragment; | ||
801 | |||
802 | if (GNUNET_OK != channel_key_store (plugin, channel_key)) | ||
803 | return GNUNET_SYSERR; | ||
804 | |||
805 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
806 | sizeof (*channel_key), SQLITE_STATIC) || | ||
807 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, msg->hop_counter ) || | ||
808 | SQLITE_OK != sqlite3_bind_blob (stmt, 3, (const void *) &msg->signature, | ||
809 | sizeof (msg->signature), SQLITE_STATIC) || | ||
810 | SQLITE_OK != sqlite3_bind_blob (stmt, 4, (const void *) &msg->purpose, | ||
811 | sizeof (msg->purpose), SQLITE_STATIC) || | ||
812 | SQLITE_OK != sqlite3_bind_int64 (stmt, 5, msg->fragment_id) || | ||
813 | SQLITE_OK != sqlite3_bind_int64 (stmt, 6, msg->fragment_offset) || | ||
814 | SQLITE_OK != sqlite3_bind_int64 (stmt, 7, msg->message_id) || | ||
815 | SQLITE_OK != sqlite3_bind_int64 (stmt, 8, msg->group_generation) || | ||
816 | SQLITE_OK != sqlite3_bind_int64 (stmt, 9, msg->flags) || | ||
817 | SQLITE_OK != sqlite3_bind_int64 (stmt, 10, psycstore_flags) || | ||
818 | SQLITE_OK != sqlite3_bind_blob (stmt, 11, (const void *) &msg[1], | ||
819 | ntohs (msg->header.size) - sizeof (*msg), | ||
820 | SQLITE_STATIC)) | ||
821 | { | ||
822 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
823 | "insert_fragment (bind)"); | ||
824 | } | ||
825 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
826 | { | ||
827 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
828 | "insert_fragment (step)"); | ||
829 | } | ||
830 | |||
831 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
832 | { | ||
833 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
834 | "insert_fragment (reset)"); | ||
835 | return GNUNET_SYSERR; | ||
836 | } | ||
633 | 837 | ||
838 | return GNUNET_OK; | ||
634 | } | 839 | } |
635 | 840 | ||
636 | /** | 841 | /** |
637 | * Set additional flags for a given message. | 842 | * Set additional flags for a given message. |
638 | * | 843 | * |
844 | * They are OR'd with any existing flags set. | ||
845 | * | ||
846 | * @param plugin Plugin handle. | ||
847 | * @param channel_key Public key of the channel. | ||
639 | * @param message_id ID of the message. | 848 | * @param message_id ID of the message. |
640 | * @param flags Flags to add. | 849 | * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags. |
641 | * | 850 | * |
642 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 851 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
643 | */ | 852 | */ |
644 | int | 853 | static int |
645 | libgnunet_plugin_psycstore_sqlite_fragment_add_flags | 854 | message_add_flags (void *cls, |
646 | (void *cls, | 855 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
647 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 856 | uint64_t message_id, |
648 | uint64_t message_id, | 857 | uint64_t psycstore_flags) |
649 | uint64_t multicast_flags, | 858 | { |
650 | uint64_t psyc_flags) { | 859 | struct Plugin *plugin = cls; |
860 | sqlite3_stmt *stmt = plugin->update_message_flags; | ||
861 | int ret = GNUNET_SYSERR; | ||
862 | |||
863 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, psycstore_flags) || | ||
864 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key, | ||
865 | sizeof (*channel_key), SQLITE_STATIC) || | ||
866 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id)) | ||
867 | { | ||
868 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
869 | "update_message_flags (bind)"); | ||
870 | } | ||
871 | else | ||
872 | { | ||
873 | switch (sqlite3_step (stmt)) | ||
874 | { | ||
875 | case SQLITE_DONE: | ||
876 | ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO; | ||
877 | break; | ||
878 | default: | ||
879 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
880 | "update_message_flags (step)"); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
885 | { | ||
886 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
887 | "update_message_flags (reset)"); | ||
888 | return GNUNET_SYSERR; | ||
889 | } | ||
890 | |||
891 | return ret; | ||
892 | } | ||
651 | 893 | ||
894 | static int | ||
895 | fragment_row (sqlite3_stmt *stmt, GNUNET_PSYCSTORE_FragmentCallback cb, | ||
896 | void *cb_cls) | ||
897 | { | ||
898 | int data_size = sqlite3_column_bytes (stmt, 9); | ||
899 | struct GNUNET_MULTICAST_MessageHeader *msg | ||
900 | = GNUNET_malloc (sizeof (*msg) + data_size); | ||
901 | |||
902 | msg->header.size = htons (sizeof (*msg) + data_size); | ||
903 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); | ||
904 | msg->hop_counter = (uint32_t) sqlite3_column_int64 (stmt, 0); | ||
905 | memcpy (&msg->signature, | ||
906 | sqlite3_column_blob (stmt, 1), | ||
907 | sqlite3_column_bytes (stmt, 1)); | ||
908 | memcpy (&msg->purpose, | ||
909 | sqlite3_column_blob (stmt, 2), | ||
910 | sqlite3_column_bytes (stmt, 2)); | ||
911 | msg->fragment_id = sqlite3_column_int64 (stmt, 3); | ||
912 | msg->fragment_offset = sqlite3_column_int64 (stmt, 4); | ||
913 | msg->message_id = sqlite3_column_int64 (stmt, 5); | ||
914 | msg->group_generation = sqlite3_column_int64 (stmt, 6); | ||
915 | msg->flags = sqlite3_column_int64 (stmt, 7); | ||
916 | memcpy (&msg[1], sqlite3_column_blob (stmt, 9), data_size); | ||
917 | |||
918 | return cb (cb_cls, (void *) msg, sqlite3_column_int64 (stmt, 8)); | ||
652 | } | 919 | } |
653 | 920 | ||
654 | /** | 921 | /** |
@@ -658,14 +925,49 @@ libgnunet_plugin_psycstore_sqlite_fragment_add_flags | |||
658 | * | 925 | * |
659 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 926 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
660 | */ | 927 | */ |
661 | int | 928 | static int |
662 | libgnunet_plugin_psycstore_sqlite_fragment_get | 929 | fragment_get (void *cls, |
663 | (void *cls, | 930 | const struct |
664 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 931 | GNUNET_CRYPTO_EccPublicKey *channel_key, |
665 | uint64_t fragment_id, | 932 | uint64_t fragment_id, |
666 | GNUNET_PSYCSTORE_FragmentCallback cb, | 933 | GNUNET_PSYCSTORE_FragmentCallback cb, |
667 | void *cb_cls) { | 934 | void *cb_cls) |
935 | { | ||
936 | struct Plugin *plugin = cls; | ||
937 | sqlite3_stmt *stmt = plugin->select_fragment; | ||
938 | int ret = GNUNET_SYSERR; | ||
939 | |||
940 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
941 | sizeof (*channel_key), | ||
942 | SQLITE_STATIC) || | ||
943 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, fragment_id)) | ||
944 | { | ||
945 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
946 | "select_fragment (bind)"); | ||
947 | } | ||
948 | else | ||
949 | { | ||
950 | switch (sqlite3_step (stmt)) | ||
951 | { | ||
952 | case SQLITE_DONE: | ||
953 | ret = GNUNET_NO; | ||
954 | break; | ||
955 | case SQLITE_ROW: | ||
956 | ret = fragment_row (stmt, cb, cb_cls); | ||
957 | break; | ||
958 | default: | ||
959 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
960 | "select_fragment (step)"); | ||
961 | } | ||
962 | } | ||
668 | 963 | ||
964 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
965 | { | ||
966 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
967 | "select_fragment (reset)"); | ||
968 | } | ||
969 | |||
970 | return ret; | ||
669 | } | 971 | } |
670 | 972 | ||
671 | /** | 973 | /** |
@@ -675,14 +977,57 @@ libgnunet_plugin_psycstore_sqlite_fragment_get | |||
675 | * | 977 | * |
676 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 978 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
677 | */ | 979 | */ |
678 | int | 980 | static int |
679 | libgnunet_plugin_psycstore_sqlite_message_get | 981 | message_get (void *cls, |
680 | (void *cls, | 982 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
681 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 983 | uint64_t message_id, |
682 | uint64_t message_id, | 984 | GNUNET_PSYCSTORE_FragmentCallback cb, |
683 | GNUNET_PSYCSTORE_FragmentCallback cb, | 985 | void *cb_cls) |
684 | void *cb_cls) { | 986 | { |
987 | struct Plugin *plugin = cls; | ||
988 | sqlite3_stmt *stmt = plugin->select_message; | ||
989 | int ret = GNUNET_SYSERR; | ||
990 | |||
991 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
992 | sizeof (*channel_key), | ||
993 | SQLITE_STATIC) || | ||
994 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id)) | ||
995 | { | ||
996 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
997 | "select_message (bind)"); | ||
998 | } | ||
999 | else | ||
1000 | { | ||
1001 | int sql_ret; | ||
1002 | do | ||
1003 | { | ||
1004 | sql_ret = sqlite3_step (stmt); | ||
1005 | switch (sql_ret) | ||
1006 | { | ||
1007 | case SQLITE_DONE: | ||
1008 | if (ret != GNUNET_OK) | ||
1009 | ret = GNUNET_NO; | ||
1010 | break; | ||
1011 | case SQLITE_ROW: | ||
1012 | ret = fragment_row (stmt, cb, cb_cls); | ||
1013 | if (ret != GNUNET_YES) | ||
1014 | sql_ret = SQLITE_DONE; | ||
1015 | break; | ||
1016 | default: | ||
1017 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1018 | "select_message (step)"); | ||
1019 | } | ||
1020 | } | ||
1021 | while (sql_ret == SQLITE_ROW); | ||
1022 | } | ||
685 | 1023 | ||
1024 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1025 | { | ||
1026 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1027 | "select_message (reset)"); | ||
1028 | } | ||
1029 | |||
1030 | return ret; | ||
686 | } | 1031 | } |
687 | 1032 | ||
688 | /** | 1033 | /** |
@@ -693,16 +1038,51 @@ libgnunet_plugin_psycstore_sqlite_message_get | |||
693 | * | 1038 | * |
694 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1039 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
695 | */ | 1040 | */ |
696 | int | 1041 | static int |
697 | libgnunet_plugin_psycstore_sqlite_message_get_fragment | 1042 | message_get_fragment (void *cls, |
698 | (void *cls, | 1043 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
699 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1044 | uint64_t message_id, |
700 | uint64_t message_id, | 1045 | uint64_t fragment_offset, |
701 | uint64_t fragment_offset, | 1046 | GNUNET_PSYCSTORE_FragmentCallback cb, |
702 | GNUNET_PSYCSTORE_FragmentCallback cb, | 1047 | void *cb_cls) |
703 | void *cb_cls) | ||
704 | { | 1048 | { |
1049 | struct Plugin *plugin = cls; | ||
1050 | int ret = GNUNET_SYSERR; | ||
1051 | |||
1052 | sqlite3_stmt *stmt = plugin->select_message_fragment; | ||
1053 | |||
1054 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1055 | sizeof (*channel_key), | ||
1056 | SQLITE_STATIC) || | ||
1057 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id) || | ||
1058 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, fragment_offset)) | ||
1059 | { | ||
1060 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1061 | "select_message_fragment (bind)"); | ||
1062 | } | ||
1063 | else | ||
1064 | { | ||
1065 | switch (sqlite3_step (stmt)) | ||
1066 | { | ||
1067 | case SQLITE_DONE: | ||
1068 | ret = GNUNET_NO; | ||
1069 | break; | ||
1070 | case SQLITE_ROW: | ||
1071 | ret = fragment_row (stmt, cb, cb_cls); | ||
1072 | break; | ||
1073 | default: | ||
1074 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1075 | "select_message_fragment (step)"); | ||
1076 | } | ||
1077 | } | ||
705 | 1078 | ||
1079 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1080 | { | ||
1081 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1082 | "select_message_fragment (reset)"); | ||
1083 | } | ||
1084 | |||
1085 | return ret; | ||
706 | } | 1086 | } |
707 | 1087 | ||
708 | /** | 1088 | /** |
@@ -712,15 +1092,50 @@ libgnunet_plugin_psycstore_sqlite_message_get_fragment | |||
712 | * | 1092 | * |
713 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1093 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
714 | */ | 1094 | */ |
715 | int | 1095 | static int |
716 | libgnunet_plugin_psycstore_sqlite_counters_get_master | 1096 | counters_get_master (void *cls, |
717 | (void *cls, | 1097 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
718 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1098 | uint64_t *fragment_id, |
719 | uint64_t *fragment_id, | 1099 | uint64_t *message_id, |
720 | uint64_t *message_id, | 1100 | uint64_t *group_generation) |
721 | uint64_t *group_generation) | ||
722 | { | 1101 | { |
1102 | struct Plugin *plugin = cls; | ||
1103 | sqlite3_stmt *stmt = plugin->select_counters_master; | ||
1104 | int ret = GNUNET_SYSERR; | ||
1105 | |||
1106 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1107 | sizeof (*channel_key), | ||
1108 | SQLITE_STATIC)) | ||
1109 | { | ||
1110 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1111 | "select_counters_master (bind)"); | ||
1112 | } | ||
1113 | else | ||
1114 | { | ||
1115 | switch (sqlite3_step (stmt)) | ||
1116 | { | ||
1117 | case SQLITE_DONE: | ||
1118 | ret = GNUNET_NO; | ||
1119 | break; | ||
1120 | case SQLITE_ROW: | ||
1121 | *fragment_id = sqlite3_column_int64 (stmt, 0); | ||
1122 | *message_id = sqlite3_column_int64 (stmt, 1); | ||
1123 | *group_generation = sqlite3_column_int64 (stmt, 2); | ||
1124 | ret = GNUNET_OK; | ||
1125 | break; | ||
1126 | default: | ||
1127 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1128 | "select_counters_master (step)"); | ||
1129 | } | ||
1130 | } | ||
723 | 1131 | ||
1132 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1133 | { | ||
1134 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1135 | "select_counters_master (reset)"); | ||
1136 | } | ||
1137 | |||
1138 | return ret; | ||
724 | } | 1139 | } |
725 | 1140 | ||
726 | /** | 1141 | /** |
@@ -730,12 +1145,48 @@ libgnunet_plugin_psycstore_sqlite_counters_get_master | |||
730 | * | 1145 | * |
731 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1146 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
732 | */ | 1147 | */ |
733 | int | 1148 | static int |
734 | libgnunet_plugin_psycstore_sqlite_counters_get_slave | 1149 | counters_get_slave (void *cls, |
735 | (void *cls, | 1150 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
736 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1151 | uint64_t *max_state_msg_id) |
737 | uint64_t *max_state_msg_id) { | 1152 | { |
1153 | struct Plugin *plugin = cls; | ||
1154 | sqlite3_stmt *stmt = plugin->select_counters_slave; | ||
1155 | int ret = GNUNET_SYSERR; | ||
1156 | |||
1157 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1158 | sizeof (*channel_key), | ||
1159 | SQLITE_STATIC) || | ||
1160 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, | ||
1161 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)) | ||
1162 | { | ||
1163 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1164 | "select_counters_slave (bind)"); | ||
1165 | } | ||
1166 | else | ||
1167 | { | ||
1168 | switch (sqlite3_step (stmt)) | ||
1169 | { | ||
1170 | case SQLITE_DONE: | ||
1171 | ret = GNUNET_NO; | ||
1172 | break; | ||
1173 | case SQLITE_ROW: | ||
1174 | *max_state_msg_id = sqlite3_column_int64 (stmt, 0); | ||
1175 | ret = GNUNET_OK; | ||
1176 | break; | ||
1177 | default: | ||
1178 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1179 | "select_counters_slave (step)"); | ||
1180 | } | ||
1181 | } | ||
738 | 1182 | ||
1183 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1184 | { | ||
1185 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1186 | "select_counters_slave (reset)"); | ||
1187 | } | ||
1188 | |||
1189 | return ret; | ||
739 | } | 1190 | } |
740 | 1191 | ||
741 | /** | 1192 | /** |
@@ -745,35 +1196,174 @@ libgnunet_plugin_psycstore_sqlite_counters_get_slave | |||
745 | * | 1196 | * |
746 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1197 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
747 | */ | 1198 | */ |
748 | int | 1199 | static int |
749 | libgnunet_plugin_psycstore_sqlite_state_set | 1200 | state_set (void *cls, |
750 | (struct GNUNET_PSYCSTORE_Handle *h, | 1201 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
751 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1202 | const char *name, const void *value, size_t value_size) |
752 | const char *name, | 1203 | { |
753 | size_t value_size, | 1204 | struct Plugin *plugin = cls; |
754 | const void *value) { | 1205 | int ret = GNUNET_SYSERR; |
1206 | |||
1207 | sqlite3_stmt *stmt = plugin->insert_state_current; | ||
1208 | |||
1209 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1210 | sizeof (*channel_key), SQLITE_STATIC) || | ||
1211 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC) || | ||
1212 | SQLITE_OK != sqlite3_bind_blob (stmt, 3, value, value_size, | ||
1213 | SQLITE_STATIC)) | ||
1214 | { | ||
1215 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1216 | "insert_state_current (bind)"); | ||
1217 | } | ||
1218 | else | ||
1219 | { | ||
1220 | switch (sqlite3_step (stmt)) | ||
1221 | { | ||
1222 | case SQLITE_DONE: | ||
1223 | ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO; | ||
1224 | break; | ||
1225 | default: | ||
1226 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1227 | "insert_state_current (step)"); | ||
1228 | } | ||
1229 | } | ||
1230 | |||
1231 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1232 | { | ||
1233 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1234 | "insert_state_current (reset)"); | ||
1235 | return GNUNET_SYSERR; | ||
1236 | } | ||
1237 | |||
1238 | return ret; | ||
1239 | } | ||
1240 | |||
1241 | |||
1242 | /** | ||
1243 | * Reset the state of a channel. | ||
1244 | * | ||
1245 | * @see GNUNET_PSYCSTORE_state_reset() | ||
1246 | * | ||
1247 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1248 | */ | ||
1249 | static int | ||
1250 | state_reset (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
1251 | { | ||
1252 | struct Plugin *plugin = cls; | ||
1253 | sqlite3_stmt *stmt = plugin->delete_state; | ||
1254 | |||
1255 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1256 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1257 | { | ||
1258 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1259 | "delete_state (bind)"); | ||
1260 | } | ||
1261 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
1262 | { | ||
1263 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1264 | "delete_state (step)"); | ||
1265 | } | ||
1266 | |||
1267 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1268 | { | ||
1269 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1270 | "delete_state (reset)"); | ||
1271 | return GNUNET_SYSERR; | ||
1272 | } | ||
1273 | |||
1274 | return GNUNET_OK; | ||
1275 | } | ||
1276 | |||
1277 | |||
1278 | /** | ||
1279 | * Update signed values of state variables in the state store. | ||
1280 | * | ||
1281 | * @see GNUNET_PSYCSTORE_state_hash_update() | ||
1282 | * | ||
1283 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1284 | */ | ||
1285 | static int | ||
1286 | state_update_signed (void *cls, | ||
1287 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
1288 | { | ||
1289 | struct Plugin *plugin = cls; | ||
1290 | sqlite3_stmt *stmt = plugin->update_state_signed; | ||
1291 | |||
1292 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1293 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1294 | { | ||
1295 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1296 | "update_state_signed (bind)"); | ||
1297 | } | ||
1298 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
1299 | { | ||
1300 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1301 | "update_state_signed (step)"); | ||
1302 | } | ||
1303 | |||
1304 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1305 | { | ||
1306 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1307 | "update_state_signed (reset)"); | ||
1308 | return GNUNET_SYSERR; | ||
1309 | } | ||
755 | 1310 | ||
1311 | return GNUNET_OK; | ||
756 | } | 1312 | } |
757 | 1313 | ||
1314 | |||
758 | /** | 1315 | /** |
759 | * Retrieve a state variable by name. | 1316 | * Retrieve a state variable by name. |
760 | * | 1317 | * |
761 | * @param name Name of the variable to retrieve. | 1318 | * @see GNUNET_PSYCSTORE_state_get() |
762 | * @param[out] value_size Size of value. | ||
763 | * @param[out] value Returned value. | ||
764 | * | 1319 | * |
765 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1320 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
766 | */ | 1321 | */ |
767 | int | 1322 | static int |
768 | libgnunet_plugin_psycstore_sqlite_state_get | 1323 | state_get (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
769 | (struct GNUNET_PSYCSTORE_Handle *h, | 1324 | const char *name, GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls) |
770 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1325 | { |
771 | const char *name, | 1326 | struct Plugin *plugin = cls; |
772 | GNUNET_PSYCSTORE_StateCallback cb, | 1327 | int ret = GNUNET_SYSERR; |
773 | void *cb_cls) { | 1328 | |
1329 | sqlite3_stmt *stmt = plugin->select_state_one; | ||
1330 | |||
1331 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1332 | sizeof (*channel_key), | ||
1333 | SQLITE_STATIC) || | ||
1334 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC)) | ||
1335 | { | ||
1336 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1337 | "select_state_one (bind)"); | ||
1338 | } | ||
1339 | else | ||
1340 | { | ||
1341 | switch (sqlite3_step (stmt)) | ||
1342 | { | ||
1343 | case SQLITE_DONE: | ||
1344 | ret = GNUNET_NO; | ||
1345 | break; | ||
1346 | case SQLITE_ROW: | ||
1347 | ret = cb (cb_cls, name, sqlite3_column_blob (stmt, 0), | ||
1348 | sqlite3_column_bytes (stmt, 0)); | ||
1349 | break; | ||
1350 | default: | ||
1351 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1352 | "select_state_one (step)"); | ||
1353 | } | ||
1354 | } | ||
774 | 1355 | ||
1356 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1357 | { | ||
1358 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1359 | "select_state_one (reset)"); | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | return ret; | ||
775 | } | 1364 | } |
776 | 1365 | ||
1366 | |||
777 | /** | 1367 | /** |
778 | * Retrieve all state variables for a channel with the given prefix. | 1368 | * Retrieve all state variables for a channel with the given prefix. |
779 | * | 1369 | * |
@@ -781,21 +1371,130 @@ libgnunet_plugin_psycstore_sqlite_state_get | |||
781 | * | 1371 | * |
782 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1372 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
783 | */ | 1373 | */ |
784 | int | 1374 | static int |
785 | libgnunet_plugin_psycstore_sqlite_state_get_all | 1375 | state_get_all (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
786 | (struct GNUNET_PSYCSTORE_Handle *h, | 1376 | const char *name, GNUNET_PSYCSTORE_StateCallback cb, |
787 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1377 | void *cb_cls) |
788 | const char *name, | 1378 | { |
789 | GNUNET_PSYCSTORE_StateCallback cb, | 1379 | struct Plugin *plugin = cls; |
790 | void *cb_cls) { | 1380 | int ret = GNUNET_SYSERR; |
1381 | |||
1382 | sqlite3_stmt *stmt = plugin->select_state_prefix; | ||
1383 | size_t name_len = strlen (name); | ||
1384 | char *name_prefix = GNUNET_malloc (name_len + 2); | ||
1385 | memcpy (name_prefix, name, name_len); | ||
1386 | memcpy (name_prefix + name_len, "_%", 2); | ||
1387 | |||
1388 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1389 | sizeof (*channel_key), SQLITE_STATIC) || | ||
1390 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, name_len, SQLITE_STATIC) || | ||
1391 | SQLITE_OK != sqlite3_bind_text (stmt, 3, name_prefix, name_len + 2, | ||
1392 | SQLITE_STATIC)) | ||
1393 | { | ||
1394 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1395 | "select_state_prefix (bind)"); | ||
1396 | } | ||
1397 | else | ||
1398 | { | ||
1399 | int sql_ret; | ||
1400 | do | ||
1401 | { | ||
1402 | sql_ret = sqlite3_step (stmt); | ||
1403 | switch (sql_ret) | ||
1404 | { | ||
1405 | case SQLITE_DONE: | ||
1406 | if (ret != GNUNET_OK) | ||
1407 | ret = GNUNET_NO; | ||
1408 | break; | ||
1409 | case SQLITE_ROW: | ||
1410 | ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0), | ||
1411 | sqlite3_column_blob (stmt, 1), | ||
1412 | sqlite3_column_bytes (stmt, 1)); | ||
1413 | if (ret != GNUNET_YES) | ||
1414 | sql_ret = SQLITE_DONE; | ||
1415 | break; | ||
1416 | default: | ||
1417 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1418 | "select_state_prefix (step)"); | ||
1419 | } | ||
1420 | } | ||
1421 | while (sql_ret == SQLITE_ROW); | ||
1422 | } | ||
1423 | |||
1424 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1425 | { | ||
1426 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1427 | "select_state_prefix (reset)"); | ||
1428 | } | ||
791 | 1429 | ||
1430 | return ret; | ||
792 | } | 1431 | } |
793 | 1432 | ||
794 | 1433 | ||
795 | /** | 1434 | /** |
1435 | * Retrieve all signed state variables for a channel. | ||
1436 | * | ||
1437 | * @see GNUNET_PSYCSTORE_state_get_signed() | ||
1438 | * | ||
1439 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1440 | */ | ||
1441 | static int | ||
1442 | state_get_signed (void *cls, | ||
1443 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
1444 | GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls) | ||
1445 | { | ||
1446 | struct Plugin *plugin = cls; | ||
1447 | int ret = GNUNET_SYSERR; | ||
1448 | |||
1449 | sqlite3_stmt *stmt = plugin->select_state_signed; | ||
1450 | |||
1451 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1452 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1453 | { | ||
1454 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1455 | "select_state_signed (bind)"); | ||
1456 | } | ||
1457 | else | ||
1458 | { | ||
1459 | int sql_ret; | ||
1460 | do | ||
1461 | { | ||
1462 | sql_ret = sqlite3_step (stmt); | ||
1463 | switch (sql_ret) | ||
1464 | { | ||
1465 | case SQLITE_DONE: | ||
1466 | if (ret != GNUNET_OK) | ||
1467 | ret = GNUNET_NO; | ||
1468 | break; | ||
1469 | case SQLITE_ROW: | ||
1470 | ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0), | ||
1471 | sqlite3_column_blob (stmt, 1), | ||
1472 | sqlite3_column_bytes (stmt, 1)); | ||
1473 | if (ret != GNUNET_YES) | ||
1474 | sql_ret = SQLITE_DONE; | ||
1475 | break; | ||
1476 | default: | ||
1477 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1478 | "select_state_signed (step)"); | ||
1479 | } | ||
1480 | } | ||
1481 | while (sql_ret == SQLITE_ROW); | ||
1482 | } | ||
1483 | |||
1484 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1485 | { | ||
1486 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1487 | "select_state_signed (reset)"); | ||
1488 | } | ||
1489 | |||
1490 | return ret; | ||
1491 | } | ||
1492 | |||
1493 | |||
1494 | /** | ||
796 | * Entry point for the plugin. | 1495 | * Entry point for the plugin. |
797 | * | 1496 | * |
798 | * @param cls the "struct GNUNET_PSYCSTORE_PluginEnvironment*" | 1497 | * @param cls The struct GNUNET_CONFIGURATION_Handle. |
799 | * @return NULL on error, otherwise the plugin context | 1498 | * @return NULL on error, otherwise the plugin context |
800 | */ | 1499 | */ |
801 | void * | 1500 | void * |
@@ -816,21 +1515,23 @@ libgnunet_plugin_psycstore_sqlite_init (void *cls) | |||
816 | } | 1515 | } |
817 | api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions); | 1516 | api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions); |
818 | api->cls = &plugin; | 1517 | api->cls = &plugin; |
819 | api->membership_store = &libgnunet_plugin_psycstore_sqlite_membership_store; | 1518 | api->membership_store = &membership_store; |
820 | api->membership_test = &libgnunet_plugin_psycstore_sqlite_membership_test; | 1519 | api->membership_test = &membership_test; |
821 | api->fragment_store = &libgnunet_plugin_psycstore_sqlite_fragment_store; | 1520 | api->fragment_store = &fragment_store; |
822 | api->fragment_add_flags = &libgnunet_plugin_psycstore_sqlite_fragment_add_flags; | 1521 | api->message_add_flags = &message_add_flags; |
823 | api->fragment_get = &libgnunet_plugin_psycstore_sqlite_fragment_get; | 1522 | api->fragment_get = &fragment_get; |
824 | api->message_get = &libgnunet_plugin_psycstore_sqlite_message_get; | 1523 | api->message_get = &message_get; |
825 | api->message_get_fragment = &libgnunet_plugin_psycstore_sqlite_message_get_fragment; | 1524 | api->message_get_fragment = &message_get_fragment; |
826 | api->counters_get_master = &libgnunet_plugin_psycstore_sqlite_counters_get_master; | 1525 | api->counters_get_master = &counters_get_master; |
827 | api->counters_get_slave = &libgnunet_plugin_psycstore_sqlite_counters_get_slave; | 1526 | api->counters_get_slave = &counters_get_slave; |
828 | api->state_set = &libgnunet_plugin_psycstore_sqlite_state_set; | 1527 | api->state_set = &state_set; |
829 | api->state_get = &libgnunet_plugin_psycstore_sqlite_state_get; | 1528 | api->state_reset = &state_reset; |
830 | api->state_get_all = &libgnunet_plugin_psycstore_sqlite_state_get_all; | 1529 | api->state_update_signed = &state_update_signed; |
831 | 1530 | api->state_get = &state_get; | |
832 | LOG (GNUNET_ERROR_TYPE_INFO, | 1531 | api->state_get_all = &state_get_all; |
833 | _("Sqlite database running\n")); | 1532 | api->state_get_signed = &state_get_signed; |
1533 | |||
1534 | LOG (GNUNET_ERROR_TYPE_INFO, _("SQLite database running\n")); | ||
834 | return api; | 1535 | return api; |
835 | } | 1536 | } |
836 | 1537 | ||
@@ -838,8 +1539,8 @@ libgnunet_plugin_psycstore_sqlite_init (void *cls) | |||
838 | /** | 1539 | /** |
839 | * Exit point from the plugin. | 1540 | * Exit point from the plugin. |
840 | * | 1541 | * |
841 | * @param cls the plugin context (as returned by "init") | 1542 | * @param cls The plugin context (as returned by "init") |
842 | * @return always NULL | 1543 | * @return Always NULL |
843 | */ | 1544 | */ |
844 | void * | 1545 | void * |
845 | libgnunet_plugin_psycstore_sqlite_done (void *cls) | 1546 | libgnunet_plugin_psycstore_sqlite_done (void *cls) |
@@ -850,8 +1551,7 @@ libgnunet_plugin_psycstore_sqlite_done (void *cls) | |||
850 | database_shutdown (plugin); | 1551 | database_shutdown (plugin); |
851 | plugin->cfg = NULL; | 1552 | plugin->cfg = NULL; |
852 | GNUNET_free (api); | 1553 | GNUNET_free (api); |
853 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1554 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SQLite plugin is finished\n"); |
854 | "sqlite plugin is finished\n"); | ||
855 | return NULL; | 1555 | return NULL; |
856 | } | 1556 | } |
857 | 1557 | ||
diff --git a/src/psycstore/psycstore.conf b/src/psycstore/psycstore.conf index 5b8dfee68..3f86d7b45 100644 --- a/src/psycstore/psycstore.conf +++ b/src/psycstore/psycstore.conf | |||
@@ -2,7 +2,7 @@ | |||
2 | AUTOSTART = YES | 2 | AUTOSTART = YES |
3 | HOME = $SERVICEHOME | 3 | HOME = $SERVICEHOME |
4 | BINARY = gnunet-service-psycstore | 4 | BINARY = gnunet-service-psycstore |
5 | UNIXPATH = /tmp/gnunet-service-psycstore.unix | 5 | UNIXPATH = /tmp/gnunet-service-psycstore.sock |
6 | UNIX_MATCH_UID = NO | 6 | UNIX_MATCH_UID = NO |
7 | UNIX_MATCH_GID = YES | 7 | UNIX_MATCH_GID = YES |
8 | DATABASE = sqlite | 8 | DATABASE = sqlite |
diff --git a/src/psycstore/psycstore.h b/src/psycstore/psycstore.h index f1a1c787a..2e3d66ec5 100644 --- a/src/psycstore/psycstore.h +++ b/src/psycstore/psycstore.h | |||
@@ -35,7 +35,7 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
35 | /** | 35 | /** |
36 | * Answer from service to client about last operation. | 36 | * Answer from service to client about last operation. |
37 | */ | 37 | */ |
38 | struct GNUNET_PSYCSTORE_ResultCodeMessage | 38 | struct ResultCodeMessage |
39 | { | 39 | { |
40 | /** | 40 | /** |
41 | * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE | 41 | * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE |
@@ -52,6 +52,32 @@ struct GNUNET_PSYCSTORE_ResultCodeMessage | |||
52 | 52 | ||
53 | }; | 53 | }; |
54 | 54 | ||
55 | |||
56 | /** | ||
57 | * @see GNUNET_PSYCSTORE_membership_store() | ||
58 | */ | ||
59 | struct MembershipStoreMessage | ||
60 | { | ||
61 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key; | ||
62 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key; | ||
63 | int did_join; | ||
64 | uint64_t announced_at; | ||
65 | uint64_t effective_since; | ||
66 | uint64_t group_generation; | ||
67 | }; | ||
68 | |||
69 | |||
70 | /** | ||
71 | * @see GNUNET_PSYCSTORE_membership_test() | ||
72 | */ | ||
73 | struct MembershipTestMessage | ||
74 | { | ||
75 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key; | ||
76 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key; | ||
77 | uint64_t message_id; | ||
78 | uint64_t group_generation; | ||
79 | }; | ||
80 | |||
55 | GNUNET_NETWORK_STRUCT_END | 81 | GNUNET_NETWORK_STRUCT_END |
56 | 82 | ||
57 | #endif | 83 | #endif |
diff --git a/src/psycstore/psycstore_api.c b/src/psycstore/psycstore_api.c index d8d5134b6..194dcc79e 100644 --- a/src/psycstore/psycstore_api.c +++ b/src/psycstore/psycstore_api.c | |||
@@ -187,7 +187,7 @@ message_handler (void *cls, | |||
187 | { | 187 | { |
188 | struct GNUNET_PSYCSTORE_Handle *h = cls; | 188 | struct GNUNET_PSYCSTORE_Handle *h = cls; |
189 | struct GNUNET_PSYCSTORE_OperationHandle *op; | 189 | struct GNUNET_PSYCSTORE_OperationHandle *op; |
190 | const struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm; | 190 | const struct ResultCodeMessage *rcm; |
191 | const char *str; | 191 | const char *str; |
192 | uint16_t size; | 192 | uint16_t size; |
193 | 193 | ||
@@ -203,22 +203,22 @@ message_handler (void *cls, | |||
203 | switch (ntohs (msg->type)) | 203 | switch (ntohs (msg->type)) |
204 | { | 204 | { |
205 | case GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE: | 205 | case GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE: |
206 | if (size < sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) | 206 | if (size < sizeof (struct ResultCodeMessage)) |
207 | { | 207 | { |
208 | GNUNET_break (0); | 208 | GNUNET_break (0); |
209 | reschedule_connect (h); | 209 | reschedule_connect (h); |
210 | return; | 210 | return; |
211 | } | 211 | } |
212 | rcm = (const struct GNUNET_PSYCSTORE_ResultCodeMessage *) msg; | 212 | rcm = (const struct ResultCodeMessage *) msg; |
213 | str = (const char *) &rcm[1]; | 213 | str = (const char *) &rcm[1]; |
214 | if ( (size > sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) && | 214 | if ( (size > sizeof (struct ResultCodeMessage)) && |
215 | ('\0' != str[size - sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) - 1]) ) | 215 | ('\0' != str[size - sizeof (struct ResultCodeMessage) - 1]) ) |
216 | { | 216 | { |
217 | GNUNET_break (0); | 217 | GNUNET_break (0); |
218 | reschedule_connect (h); | 218 | reschedule_connect (h); |
219 | return; | 219 | return; |
220 | } | 220 | } |
221 | if (size == sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) | 221 | if (size == sizeof (struct ResultCodeMessage)) |
222 | str = NULL; | 222 | str = NULL; |
223 | 223 | ||
224 | op = h->op_head; | 224 | op = h->op_head; |
@@ -341,7 +341,6 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
341 | h->client = GNUNET_CLIENT_connect ("psycstore", h->cfg); | 341 | h->client = GNUNET_CLIENT_connect ("psycstore", h->cfg); |
342 | GNUNET_assert (NULL != h->client); | 342 | GNUNET_assert (NULL != h->client); |
343 | transmit_next (h); | 343 | transmit_next (h); |
344 | GNUNET_assert (NULL != h->th); | ||
345 | } | 344 | } |
346 | 345 | ||
347 | 346 | ||
@@ -399,7 +398,7 @@ GNUNET_PSYCSTORE_disconnect (struct GNUNET_PSYCSTORE_Handle *h) | |||
399 | * was already transmitted, the service may still choose to complete | 398 | * was already transmitted, the service may still choose to complete |
400 | * the operation. | 399 | * the operation. |
401 | * | 400 | * |
402 | * @param op operation to cancel | 401 | * @param op Operation to cancel. |
403 | */ | 402 | */ |
404 | void | 403 | void |
405 | GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op) | 404 | GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op) |
@@ -435,4 +434,33 @@ GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op) | |||
435 | } | 434 | } |
436 | 435 | ||
437 | 436 | ||
437 | struct GNUNET_PSYCSTORE_OperationHandle * | ||
438 | GNUNET_PSYCSTORE_membership_store ( | ||
439 | struct GNUNET_PSYCSTORE_Handle *h, | ||
440 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
441 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | ||
442 | int did_join, | ||
443 | uint64_t announced_at, | ||
444 | uint64_t effective_since, | ||
445 | uint64_t group_generation, | ||
446 | GNUNET_PSYCSTORE_ResultCallback rcb, | ||
447 | void *rcb_cls) | ||
448 | { | ||
449 | |||
450 | } | ||
451 | |||
452 | |||
453 | struct GNUNET_PSYCSTORE_OperationHandle * | ||
454 | GNUNET_PSYCSTORE_membership_test ( | ||
455 | struct GNUNET_PSYCSTORE_Handle *h, | ||
456 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
457 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | ||
458 | uint64_t message_id, | ||
459 | uint64_t group_generation, | ||
460 | GNUNET_PSYCSTORE_ResultCallback rcb, | ||
461 | void *rcb_cls) | ||
462 | { | ||
463 | |||
464 | } | ||
465 | |||
438 | /* end of psycstore_api.c */ | 466 | /* end of psycstore_api.c */ |
diff --git a/src/psycstore/test_plugin_psycstore.c b/src/psycstore/test_plugin_psycstore.c new file mode 100644 index 000000000..52a306f07 --- /dev/null +++ b/src/psycstore/test_plugin_psycstore.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
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 | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /* | ||
21 | * @file psycstore/test_plugin_psycstore.c | ||
22 | * @brief Test for the psycstore plugins | ||
23 | * @author Gabor X Toth | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_psycstore_plugin.h" | ||
30 | #include "gnunet_psycstore_service.h" | ||
31 | #include "gnunet_multicast_service.h" | ||
32 | |||
33 | #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING | ||
34 | #if DEBUG_PSYCSTORE | ||
35 | # define LOG_LEVEL "DEBUG" | ||
36 | #else | ||
37 | # define LOG_LEVEL "WARNING" | ||
38 | #endif | ||
39 | |||
40 | #define C2ARG(str) str, (sizeof (str) - 1) | ||
41 | |||
42 | #define LOG(kind,...) GNUNET_log_from (kind, "test-plugin-psycstore", __VA_ARGS__) | ||
43 | |||
44 | #define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, __LINE__); goto FAILURE;} } while (0) | ||
45 | |||
46 | static int ok; | ||
47 | |||
48 | /** | ||
49 | * Name of plugin under test. | ||
50 | */ | ||
51 | static const char *plugin_name; | ||
52 | |||
53 | static struct GNUNET_CRYPTO_EccPrivateKey *channel_key; | ||
54 | static struct GNUNET_CRYPTO_EccPrivateKey *slave_key; | ||
55 | |||
56 | static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key; | ||
57 | static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key; | ||
58 | |||
59 | /** | ||
60 | * Function called when the service shuts down. Unloads our psycstore | ||
61 | * plugin. | ||
62 | * | ||
63 | * @param api api to unload | ||
64 | */ | ||
65 | static void | ||
66 | unload_plugin (struct GNUNET_PSYCSTORE_PluginFunctions *api) | ||
67 | { | ||
68 | char *libname; | ||
69 | |||
70 | GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); | ||
71 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api)); | ||
72 | GNUNET_free (libname); | ||
73 | } | ||
74 | |||
75 | |||
76 | /** | ||
77 | * Load the psycstore plugin. | ||
78 | * | ||
79 | * @param cfg configuration to pass | ||
80 | * @return NULL on error | ||
81 | */ | ||
82 | static struct GNUNET_PSYCSTORE_PluginFunctions * | ||
83 | load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
84 | { | ||
85 | struct GNUNET_PSYCSTORE_PluginFunctions *ret; | ||
86 | char *libname; | ||
87 | |||
88 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' psycstore plugin\n"), | ||
89 | plugin_name); | ||
90 | GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); | ||
91 | if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg))) | ||
92 | { | ||
93 | FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name); | ||
94 | return NULL; | ||
95 | } | ||
96 | GNUNET_free (libname); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | |||
101 | struct FragmentClosure | ||
102 | { | ||
103 | uint8_t n; | ||
104 | uint64_t flags[16]; | ||
105 | struct GNUNET_MULTICAST_MessageHeader *msg[16]; | ||
106 | }; | ||
107 | |||
108 | static int | ||
109 | fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2, | ||
110 | enum GNUNET_PSYCSTORE_MessageFlags flags) | ||
111 | { | ||
112 | struct FragmentClosure *fcls = cls; | ||
113 | struct GNUNET_MULTICAST_MessageHeader *msg1 = fcls->msg[fcls->n]; | ||
114 | uint64_t flags1 = fcls->flags[fcls->n++]; | ||
115 | int ret; | ||
116 | |||
117 | if (flags1 == flags && msg1->header.size == msg2->header.size | ||
118 | && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size))) | ||
119 | { | ||
120 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n", | ||
121 | msg1->fragment_id); | ||
122 | ret = GNUNET_YES; | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n", | ||
127 | msg1->fragment_id); | ||
128 | ret = GNUNET_SYSERR; | ||
129 | } | ||
130 | |||
131 | GNUNET_free (msg2); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | |||
136 | struct StateClosure { | ||
137 | size_t n; | ||
138 | void *value[16]; | ||
139 | size_t value_size[16]; | ||
140 | }; | ||
141 | |||
142 | static int | ||
143 | state_cb (void *cls, const char *name, const void *value, size_t value_size) | ||
144 | { | ||
145 | struct StateClosure *scls = cls; | ||
146 | const void *val = scls->value[scls->n]; | ||
147 | size_t val_size = scls->value_size[scls->n++]; | ||
148 | |||
149 | return value_size == val_size && 0 == memcmp (value, val, val_size) | ||
150 | ? GNUNET_YES | ||
151 | : GNUNET_SYSERR; | ||
152 | } | ||
153 | |||
154 | |||
155 | static void | ||
156 | run (void *cls, char *const *args, const char *cfgfile, | ||
157 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
158 | { | ||
159 | struct GNUNET_PSYCSTORE_PluginFunctions *db; | ||
160 | |||
161 | ok = 1; | ||
162 | db = load_plugin (cfg); | ||
163 | if (NULL == db) | ||
164 | { | ||
165 | FPRINTF (stderr, | ||
166 | "%s", | ||
167 | "Failed to initialize PSYCstore. " | ||
168 | "Database likely not setup, skipping test.\n"); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | /* Membership */ | ||
173 | |||
174 | channel_key = GNUNET_CRYPTO_ecc_key_create (); | ||
175 | slave_key = GNUNET_CRYPTO_ecc_key_create (); | ||
176 | |||
177 | GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key); | ||
178 | GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key); | ||
179 | |||
180 | ASSERT (GNUNET_OK == db->membership_store(db->cls, &channel_pub_key, | ||
181 | &slave_pub_key, GNUNET_YES, | ||
182 | 4, 2, 1)); | ||
183 | |||
184 | ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key, | ||
185 | &slave_pub_key, 4)); | ||
186 | |||
187 | ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key, | ||
188 | &slave_pub_key, 2)); | ||
189 | |||
190 | ASSERT (GNUNET_NO == db->membership_test(db->cls, &channel_pub_key, | ||
191 | &slave_pub_key, 1)); | ||
192 | |||
193 | |||
194 | /* Messages */ | ||
195 | |||
196 | struct GNUNET_MULTICAST_MessageHeader *msg | ||
197 | = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key)); | ||
198 | ASSERT (msg != NULL); | ||
199 | |||
200 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); | ||
201 | msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key)); | ||
202 | |||
203 | msg->hop_counter = 9; | ||
204 | msg->fragment_id = INT64_MAX - 1; | ||
205 | msg->fragment_offset = 0; | ||
206 | msg->message_id = INT64_MAX - 2; | ||
207 | msg->group_generation = INT64_MAX - 3; | ||
208 | msg->flags = GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT; | ||
209 | |||
210 | memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key)); | ||
211 | |||
212 | msg->purpose.size = htonl (ntohs (msg->header.size) | ||
213 | - sizeof (msg->header) | ||
214 | - sizeof (msg->hop_counter) | ||
215 | - sizeof (msg->signature)); | ||
216 | msg->purpose.purpose = htonl (234); | ||
217 | GNUNET_CRYPTO_ecc_sign (slave_key, &msg->purpose, &msg->signature); | ||
218 | |||
219 | struct FragmentClosure fcls = { 0 }; | ||
220 | fcls.n = 0; | ||
221 | fcls.msg[0] = msg; | ||
222 | fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE; | ||
223 | |||
224 | ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg, | ||
225 | fcls.flags[0])); | ||
226 | |||
227 | ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, | ||
228 | msg->fragment_id, | ||
229 | fragment_cb, &fcls)); | ||
230 | ASSERT (fcls.n == 1); | ||
231 | |||
232 | fcls.n = 0; | ||
233 | |||
234 | ASSERT (GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key, | ||
235 | msg->message_id, | ||
236 | msg->fragment_offset, | ||
237 | fragment_cb, &fcls)); | ||
238 | ASSERT (fcls.n == 1); | ||
239 | |||
240 | ASSERT (GNUNET_OK == db->message_add_flags ( | ||
241 | db->cls, &channel_pub_key, msg->message_id, | ||
242 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)); | ||
243 | |||
244 | fcls.n = 0; | ||
245 | fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED; | ||
246 | |||
247 | ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, | ||
248 | msg->fragment_id, | ||
249 | fragment_cb, &fcls)); | ||
250 | ASSERT (fcls.n == 1); | ||
251 | |||
252 | struct GNUNET_MULTICAST_MessageHeader *msg1 | ||
253 | = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key)); | ||
254 | |||
255 | memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key)); | ||
256 | |||
257 | msg1->fragment_id++; | ||
258 | msg1->fragment_offset += 32768; | ||
259 | |||
260 | fcls.n = 0; | ||
261 | fcls.msg[1] = msg1; | ||
262 | fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH; | ||
263 | |||
264 | ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1, | ||
265 | fcls.flags[1])); | ||
266 | |||
267 | ASSERT (GNUNET_OK == db->message_get (db->cls, &channel_pub_key, | ||
268 | msg->message_id, | ||
269 | fragment_cb, &fcls)); | ||
270 | ASSERT (fcls.n == 2); | ||
271 | |||
272 | uint64_t max_state_msg_id = 0; | ||
273 | ASSERT (GNUNET_OK == db->counters_get_slave (db->cls, &channel_pub_key, | ||
274 | &max_state_msg_id) | ||
275 | && max_state_msg_id == msg->message_id); | ||
276 | |||
277 | uint64_t fragment_id = 0, message_id = 0, group_generation = 0; | ||
278 | ASSERT (GNUNET_OK == db->counters_get_master (db->cls, &channel_pub_key, | ||
279 | &fragment_id, &message_id, | ||
280 | &group_generation) | ||
281 | && fragment_id == msg1->fragment_id | ||
282 | && message_id == msg1->message_id | ||
283 | && group_generation == msg1->group_generation); | ||
284 | |||
285 | |||
286 | /* State */ | ||
287 | |||
288 | ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo", | ||
289 | C2ARG("one two three"))); | ||
290 | |||
291 | ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo_bar", | ||
292 | slave_key, | ||
293 | sizeof (*slave_key))); | ||
294 | |||
295 | struct StateClosure scls = { 0 }; | ||
296 | scls.n = 0; | ||
297 | scls.value[0] = "one two three"; | ||
298 | scls.value_size[0] = strlen ("one two three"); | ||
299 | |||
300 | ASSERT (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo", | ||
301 | state_cb, &scls)); | ||
302 | ASSERT (scls.n == 1); | ||
303 | |||
304 | scls.n = 0; | ||
305 | scls.value[1] = slave_key; | ||
306 | scls.value_size[1] = sizeof (*slave_key); | ||
307 | |||
308 | ASSERT (GNUNET_OK == db->state_get_all (db->cls, &channel_pub_key, "_foo", | ||
309 | state_cb, &scls)); | ||
310 | ASSERT (scls.n == 2); | ||
311 | |||
312 | scls.n = 0; | ||
313 | ASSERT (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key, | ||
314 | state_cb, &scls)); | ||
315 | ASSERT (scls.n == 0); | ||
316 | |||
317 | ASSERT (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key)); | ||
318 | |||
319 | scls.n = 0; | ||
320 | ASSERT (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key, | ||
321 | state_cb, &scls)); | ||
322 | ASSERT (scls.n == 2); | ||
323 | |||
324 | ok = 0; | ||
325 | |||
326 | FAILURE: | ||
327 | |||
328 | if (NULL != channel_key) | ||
329 | { | ||
330 | GNUNET_free (channel_key); | ||
331 | channel_key = NULL; | ||
332 | } | ||
333 | if (NULL != slave_key) | ||
334 | { | ||
335 | GNUNET_free (slave_key); | ||
336 | slave_key = NULL; | ||
337 | } | ||
338 | |||
339 | unload_plugin (db); | ||
340 | } | ||
341 | |||
342 | |||
343 | int | ||
344 | main (int argc, char *argv[]) | ||
345 | { | ||
346 | char cfg_name[128]; | ||
347 | char *const xargv[] = { | ||
348 | "test-plugin-psycstore", | ||
349 | "-c", cfg_name, | ||
350 | "-L", LOG_LEVEL, | ||
351 | NULL | ||
352 | }; | ||
353 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
354 | GNUNET_GETOPT_OPTION_END | ||
355 | }; | ||
356 | |||
357 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite"); | ||
358 | GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL); | ||
359 | plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); | ||
360 | GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_psycstore_%s.conf", | ||
361 | plugin_name); | ||
362 | GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, | ||
363 | "test-plugin-psycstore", "nohelp", options, &run, NULL); | ||
364 | |||
365 | if (ok != 0) | ||
366 | FPRINTF (stderr, "Missed some testcases: %d\n", ok); | ||
367 | |||
368 | #if ! DEBUG_PSYCSTORE | ||
369 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite"); | ||
370 | #endif | ||
371 | |||
372 | return ok; | ||
373 | } | ||
374 | |||
375 | /* end of test_plugin_psycstore.c */ | ||
diff --git a/src/psycstore/test_plugin_psycstore_sqlite.conf b/src/psycstore/test_plugin_psycstore_sqlite.conf new file mode 100644 index 000000000..7cde6fa4c --- /dev/null +++ b/src/psycstore/test_plugin_psycstore_sqlite.conf | |||
@@ -0,0 +1,2 @@ | |||
1 | [psycstore-sqlite] | ||
2 | FILENAME = /tmp/gnunet-test-plugin-psycstore-sqlite/sqlite.db | ||
diff --git a/src/psycstore/test_psycstore.c b/src/psycstore/test_psycstore.c index 405d1622c..6b9e77180 100644 --- a/src/psycstore/test_psycstore.c +++ b/src/psycstore/test_psycstore.c | |||
@@ -48,13 +48,18 @@ static struct GNUNET_PSYCSTORE_Handle *h; | |||
48 | /** | 48 | /** |
49 | * Handle to PSYCstore operation. | 49 | * Handle to PSYCstore operation. |
50 | */ | 50 | */ |
51 | static struct GNUNET_PSYCSTORE_Operation *op; | 51 | static struct GNUNET_PSYCSTORE_OperationHandle *op; |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Handle for task for timeout termination. | 54 | * Handle for task for timeout termination. |
55 | */ | 55 | */ |
56 | static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; | 56 | static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; |
57 | 57 | ||
58 | static struct GNUNET_CRYPTO_EccPrivateKey *channel_key; | ||
59 | static struct GNUNET_CRYPTO_EccPrivateKey *slave_key; | ||
60 | |||
61 | static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key; | ||
62 | static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key; | ||
58 | 63 | ||
59 | /** | 64 | /** |
60 | * Clean up all resources used. | 65 | * Clean up all resources used. |
@@ -72,6 +77,16 @@ cleanup () | |||
72 | GNUNET_PSYCSTORE_disconnect (h); | 77 | GNUNET_PSYCSTORE_disconnect (h); |
73 | h = NULL; | 78 | h = NULL; |
74 | } | 79 | } |
80 | if (NULL != channel_key) | ||
81 | { | ||
82 | GNUNET_free (channel_key); | ||
83 | channel_key = NULL; | ||
84 | } | ||
85 | if (NULL != slave_key) | ||
86 | { | ||
87 | GNUNET_free (slave_key); | ||
88 | slave_key = NULL; | ||
89 | } | ||
75 | GNUNET_SCHEDULER_shutdown (); | 90 | GNUNET_SCHEDULER_shutdown (); |
76 | } | 91 | } |
77 | 92 | ||
@@ -119,6 +134,11 @@ end () | |||
119 | &end_normally, NULL); | 134 | &end_normally, NULL); |
120 | } | 135 | } |
121 | 136 | ||
137 | void | ||
138 | membership_store_result (void *cls, int result, const char *err_msg) | ||
139 | { | ||
140 | |||
141 | } | ||
122 | 142 | ||
123 | /** | 143 | /** |
124 | * Main function of the test, run from scheduler. | 144 | * Main function of the test, run from scheduler. |
@@ -136,6 +156,17 @@ run (void *cls, | |||
136 | &endbadly, NULL); | 156 | &endbadly, NULL); |
137 | h = GNUNET_PSYCSTORE_connect (cfg); | 157 | h = GNUNET_PSYCSTORE_connect (cfg); |
138 | GNUNET_assert (NULL != h); | 158 | GNUNET_assert (NULL != h); |
159 | |||
160 | channel_key = GNUNET_CRYPTO_ecc_key_create (); | ||
161 | slave_key = GNUNET_CRYPTO_ecc_key_create (); | ||
162 | |||
163 | GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key); | ||
164 | GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key); | ||
165 | |||
166 | op = GNUNET_PSYCSTORE_membership_store (h, &channel_pub_key, &slave_pub_key, | ||
167 | GNUNET_YES, 2, 2, 1, | ||
168 | &membership_store_result, NULL); | ||
169 | |||
139 | end (); | 170 | end (); |
140 | } | 171 | } |
141 | 172 | ||
diff --git a/src/psycstore/test_psycstore.conf b/src/psycstore/test_psycstore.conf index 1f6d279ab..ea3031524 100644 --- a/src/psycstore/test_psycstore.conf +++ b/src/psycstore/test_psycstore.conf | |||
@@ -3,4 +3,13 @@ DEFAULTSERVICES = psycstore | |||
3 | UNIXPATH = /tmp/test-psycstore-service-arm.sock | 3 | UNIXPATH = /tmp/test-psycstore-service-arm.sock |
4 | 4 | ||
5 | [psycstore] | 5 | [psycstore] |
6 | DBFILE = /tmp/test-psycstore-service.sqlite | 6 | AUTOSTART = YES |
7 | HOME = $SERVICEHOME | ||
8 | BINARY = gnunet-service-psycstore | ||
9 | UNIXPATH = /tmp/test-gnunet-service-psycstore.sock | ||
10 | UNIX_MATCH_UID = NO | ||
11 | UNIX_MATCH_GID = YES | ||
12 | DATABASE = sqlite | ||
13 | |||
14 | [psycstore-sqlite] | ||
15 | FILENAME = $SERVICEHOME/psycstore/sqlite_test.db | ||