[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r28974 - in gnunet/src: include psycstore
From: |
gnunet |
Subject: |
[GNUnet-SVN] r28974 - in gnunet/src: include psycstore |
Date: |
Wed, 4 Sep 2013 00:33:21 +0200 |
Author: tg
Date: 2013-09-04 00:33:21 +0200 (Wed, 04 Sep 2013)
New Revision: 28974
Added:
gnunet/src/psycstore/test_plugin_psycstore.c
gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf
Modified:
gnunet/src/include/gnunet_multicast_service.h
gnunet/src/include/gnunet_protocols.h
gnunet/src/include/gnunet_psyc_service.h
gnunet/src/include/gnunet_psycstore_plugin.h
gnunet/src/include/gnunet_psycstore_service.h
gnunet/src/include/gnunet_social_service.h
gnunet/src/psycstore/Makefile.am
gnunet/src/psycstore/gnunet-service-psycstore.c
gnunet/src/psycstore/plugin_psycstore_sqlite.c
gnunet/src/psycstore/psycstore.conf
gnunet/src/psycstore/psycstore.h
gnunet/src/psycstore/psycstore_api.c
gnunet/src/psycstore/test_psycstore.c
gnunet/src/psycstore/test_psycstore.conf
Log:
PSYCstore SQLite backend; API fixes/enhancements
Modified: gnunet/src/include/gnunet_multicast_service.h
===================================================================
--- gnunet/src/include/gnunet_multicast_service.h 2013-09-03 19:16:43 UTC
(rev 28973)
+++ gnunet/src/include/gnunet_multicast_service.h 2013-09-03 22:33:21 UTC
(rev 28974)
@@ -101,7 +101,7 @@
* unicast requests from members. Updated at each hop and thus not signed
and
* not secure.
*/
- uint32_t hop_counter GNUNET_PACKED;
+ uint32_t hop_counter;
/**
* ECC signature of the message fragment.
@@ -118,19 +118,19 @@
/**
* Number of the message fragment, monotonically increasing.
*/
- uint64_t fragment_id GNUNET_PACKED;
+ uint64_t fragment_id;
/**
* Byte offset of this @e fragment of the @e message.
*/
- uint64_t fragment_offset GNUNET_PACKED;
+ uint64_t fragment_offset;
/**
* Number of the message this fragment belongs to.
*
* Set in GNUNET_MULTICAST_origin_to_all().
*/
- uint64_t message_id GNUNET_PACKED;
+ uint64_t message_id;
/**
* Counter that monotonically increases whenever a member parts the group.
@@ -142,15 +142,15 @@
* is still the same before and after the missed messages, it means that no
* @e join or @e part operations happened during the missed messages.
*/
- uint64_t group_generation GNUNET_PACKED;
+ uint64_t group_generation;
/**
* Flags for this message fragment.
*/
- enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
+ uint32_t flags;
/* Followed by message body. */
-};
+} GNUNET_PACKED;
GNUNET_NETWORK_STRUCT_END
@@ -309,7 +309,7 @@
/**
* Functions with this signature are called whenever the multicast service
needs
- * a message to be replayed.
+ * a message fragemnt to be replayed by fragment_id.
*
* Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
* (with a message or an error); however, if the origin is destroyed or the
@@ -331,7 +331,7 @@
/**
* Functions with this signature are called whenever the multicast service
needs
- * a message to be replayed.
+ * a message fragment to be replayed by message_id and fragment_offset.
*
* Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
* (with a message or an error); however, if the origin is destroyed or the
@@ -404,9 +404,9 @@
* @param ec Error code.
*/
void
-GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
- const struct GNUNET_MessageHeader *msg,
- enum GNUNET_MULTICAST_ReplayErrorCode ec);
+GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh,
+ const struct GNUNET_MessageHeader *msg,
+ enum GNUNET_MULTICAST_ReplayErrorCode ec);
/**
@@ -417,7 +417,7 @@
* @param rh Replay session to end.
*/
void
-GNUNET_MULTICAST_replay_end (struct GNUNET_MULTICAST_ReplayHandle *rh);
+GNUNET_MULTICAST_replay_response_end (struct GNUNET_MULTICAST_ReplayHandle
*rh);
/**
@@ -426,9 +426,9 @@
* @see GNUNET_MULTICAST_replay2()
*/
typedef int
-(*GNUNET_MULTICAST_ReplayTransmitNotify)(void *cls,
- size_t *data_size,
- void *data);
+(*GNUNET_MULTICAST_ReplayTransmitNotify) (void *cls,
+ size_t *data_size,
+ void *data);
/**
@@ -439,9 +439,9 @@
* @param notify_cls Closure for @a notify.
*/
void
-GNUNET_MULTICAST_replay2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
- GNUNET_MULTICAST_ReplayTransmitNotify notify,
- void *notify_cls);
+GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
+ GNUNET_MULTICAST_ReplayTransmitNotify
notify,
+ void *notify_cls);
/**
@@ -465,7 +465,8 @@
* when restarting the origin. 0 for a new group.
* @param join_cb Function called to approve / disapprove joining of a peer.
* @param test_cb Function multicast can use to test group membership.
- * @param replay_cb Function that can be called to replay a message.
+ * @param replay_frag_cb Function that can be called to replay a message
fragment.
+ * @param replay_msg_cb Function that can be called to replay a message.
* @param request_cb Function called with message fragments from group members.
* @param message_cb Function called with the message fragments sent to the
* network by GNUNET_MULTICAST_origin_to_all(). These message fragments
@@ -486,12 +487,13 @@
void *cls);
/**
- * Function called to provide data for a transmission from the origin to all
members.
+ * Function called to provide data for a transmission from the origin to all
+ * members.
*/
typedef int
-(*GNUNET_MULTICAST_OriginTransmitNotify)(void *cls,
- size_t *data_size,
- void *data);
+(*GNUNET_MULTICAST_OriginTransmitNotify) (void *cls,
+ size_t *data_size,
+ void *data);
/**
@@ -568,16 +570,14 @@
* @a relay (might, for example, contain a user, bind user
* identity/pseudonym to peer identity, application-level message to
* origin, etc.).
- * @param max_known_fragment_id Largest known message fragment ID to the replay
- * service; all messages with IDs larger than this ID will be replayed
if
- * possible (lower IDs will be considered known and thus only
- * be replayed upon explicit request).
- * FIXME: needed? can be optional or moved to a separate function.
* @param join_cb Function called to approve / disapprove joining of a peer.
* @param test_cb Function multicast can use to test group membership.
- * @param replay_cb Function that can be called to replay messages
- * this peer already knows from this group; NULL if this
+ * @param replay_frag_cb Function that can be called to replay message
fragments
+ * this peer already knows from this group. NULL if this
* client is unable to support replay.
+ * @param replay_msg_cb Function that can be called to replay message fragments
+ * this peer already knows from this group. NULL if this
+ * client is unable to support replay.
* @param message_cb Function to be called for all message fragments we
* receive from the group, excluding those our @a replay_cb
* already has.
@@ -597,9 +597,9 @@
GNUNET_MULTICAST_ReplayFragmentCallback
replay_frag_cb,
GNUNET_MULTICAST_ReplayMessageCallback
replay_msg_cb,
GNUNET_MULTICAST_MessageCallback message_cb,
- void *cls);
+ void *cls)
+;
-
/**
* Handle for a replay request.
*/
@@ -633,16 +633,10 @@
* needed and not known to the client.
*
* @param member Membership handle.
- * @param fragment_id ID of a message fragment that this client would like to
- see replayed.
- * @param message_id ID of a message that this client would like to see
- * replayed. Typically only one of the @a fragment_id and @a message_id
- * is given. Specifying a @a message_id would return the last fragment
- * of the message, which allows requesting the preceding fragments of
the
- * message by looking at the @e fragment_delta header field.
+ * @param message_id ID of the message this client would like to see replayed.
+ * @param fragment_offset Offset of the fragment within the message to replay.
* @param flags Additional flags for the replay request. It is used & defined
- * by the replay callback. E.g. the PSYC service would use this to
- * implement state synchronization.
+ * by the replay callback.
* @param result_cb Function to be called for the replayed message.
* @param result_cb_cls Closure for @a message_cb.
* @return Replay request handle, NULL on error.
@@ -679,7 +673,7 @@
GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member);
-/**
+/**
* Function called to provide data for a transmission from a member to the
origin.
*
* @param cls closure
@@ -688,9 +682,9 @@
* @return number of bytes copied to data
*/
typedef int
-(*GNUNET_MULTICAST_MemberTransmitNotify)(void *cls,
- size_t *data_size,
- void *data);
+(*GNUNET_MULTICAST_MemberTransmitNotify) (void *cls,
+ size_t *data_size,
+ void *data);
/**
Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h 2013-09-03 19:16:43 UTC (rev
28973)
+++ gnunet/src/include/gnunet_protocols.h 2013-09-03 22:33:21 UTC (rev
28974)
@@ -1997,7 +1997,7 @@
/**
* Multicast message from the origin to all members.
*/
-#define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE
+#define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE 700
/**
* A unicast message from a group member to the origin.
Modified: gnunet/src/include/gnunet_psyc_service.h
===================================================================
--- gnunet/src/include/gnunet_psyc_service.h 2013-09-03 19:16:43 UTC (rev
28973)
+++ gnunet/src/include/gnunet_psyc_service.h 2013-09-03 22:33:21 UTC (rev
28974)
@@ -208,9 +208,9 @@
* @param modifier_count Number of elements in the @a modifiers array.
* @param modifiers State modifiers and transient variables for the message.
* @param data_offset Byte offset of @a data in the overall data of the method.
- * @param data_size Number of bytes in @a data.
* @param data Data stream given to the method (might not be zero-terminated
* if data is binary).
+ * @param data_size Number of bytes in @a data.
* @param frag Fragmentation status for the data.
*/
typedef int
@@ -221,8 +221,8 @@
size_t modifier_count,
const struct GNUNET_ENV_Modifier *modifiers,
uint64_t data_offset,
+ const void *data,
size_t data_size,
- const void *data,
enum GNUNET_PSYC_MessageFlags flags);
@@ -234,9 +234,10 @@
* @param method_name Method name in the join request.
* @param variable_count Number of elements in the @a variables array.
* @param variables Transient variables for the join request.
- * @param data_size Number of bytes in @a data.
* @param data Data stream given to the method (might not be zero-terminated
* if data is binary).
+ * @param data_size Number of bytes in @a data.
+ * @param jh Join handle to use with GNUNET_PSYC_join_decision()
*/
typedef int
(*GNUNET_PSYC_JoinCallback) (void *cls,
@@ -244,8 +245,8 @@
const char *method_name,
size_t variable_count,
const struct GNUNET_ENV_Modifier *variables,
+ const void *data,
size_t data_size,
- const void *data,
struct GNUNET_PSYC_JoinHandle *jh);
@@ -268,8 +269,8 @@
* peer identity in this array.
* @param method_name Method name for the message transmitted with the
response.
* @param env Environment containing transient variables for the message, or
NULL.
+ * @param data Data of the message.
* @param data_size Size of @a data.
- * @param data Data of the message.
*/
void
GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
@@ -278,8 +279,8 @@
const struct GNUNET_PeerIdentity *relays,
const char *method_name,
const struct GNUNET_ENV_Environment *env,
- size_t data_size,
- const void *data);
+ const void *data,
+ size_t data_size);
/**
@@ -333,23 +334,22 @@
* @param cls Closure.
* @param message_id Set to the unique message ID that was generated for
* this message.
- * @param[in,out] data_size Initially set to the number of bytes available in
@a data,
- * should be set to the number of bytes written to data (IN/OUT).
- * @param[out] data Where to write the body of the message to give to the
method;
- * function must copy at most @a *data_size bytes to @a data.
+ * @param[in,out] data_size Initially set to the number of bytes available in
+ * @a data, should be set to the number of bytes written to data.
+ * @param[out] data Where to write the body of the message to give to the
+ * method. The function must copy at most @a data_size bytes to @a
data.
* @return #GNUNET_SYSERR on error (fatal, aborts transmission)
* #GNUNET_NO on success, if more data is to be transmitted later
- * (should be used if @a *data_size was not big enough to take all the
data)
+ * (should be used if @a data_size was not big enough to take all the
data)
* #GNUNET_YES if this completes the transmission (all data supplied)
*/
typedef int
-(*GNUNET_PSYC_MasterTransmitNotify)(void *cls,
- uint64_t message_id,
- size_t *data_size,
- void *data);
+(*GNUNET_PSYC_MasterTransmitNotify) (void *cls,
+ uint64_t message_id,
+ size_t *data_size,
+ void *data);
-
/**
* Flags for transmitting messages to a channel by the master.
*/
@@ -450,8 +450,8 @@
* @param cls Closure for @a method_cb and @a join_cb.
* @param method_name Method name for the join request.
* @param env Environment containing transient variables for the request, or
NULL.
+ * @param data Payload for the join message.
* @param data_size Number of bytes in @a data.
- * @param data Payload for the join message.
* @return Handle for the slave, NULL on error.
*/
struct GNUNET_PSYC_Slave *
@@ -466,8 +466,8 @@
void *cls,
const char *method_name,
const struct GNUNET_ENV_Environment *env,
- size_t data_size,
- const void *data);
+ const void *data,
+ size_t data_size);
/**
@@ -618,7 +618,6 @@
* @param channel Channel handle.
* @param slave_key Identity of channel slave to remove.
* @param announced_at ID of the message that announced the membership change.
- * @param effective_since Removal of slave is in effect since this message ID.
*/
void
GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel,
@@ -632,14 +631,14 @@
* @param cls Closure.
* @param name Name of the state variable. A NULL value indicates that there
* are no more state variables to be returned.
+ * @param value Value of the state variable.
* @param value_size Number of bytes in @a value.
- * @param value Value of the state variable.
*/
typedef void
(*GNUNET_PSYC_StateCallback) (void *cls,
const char *name,
- size_t value_size,
- const void *value);
+ const void *value,
+ size_t value_size);
/**
Modified: gnunet/src/include/gnunet_psycstore_plugin.h
===================================================================
--- gnunet/src/include/gnunet_psycstore_plugin.h 2013-09-03 19:16:43 UTC
(rev 28973)
+++ gnunet/src/include/gnunet_psycstore_plugin.h 2013-09-03 22:33:21 UTC
(rev 28974)
@@ -40,7 +40,7 @@
/**
- * @brief struct returned by the initialization function of the plugin
+ * Struct returned by the initialization function of the plugin.
*/
struct GNUNET_PSYCSTORE_PluginFunctions
{
@@ -59,9 +59,9 @@
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
- (*membership_store) (void *cls,
- const struct GNUNET_HashCode *channel_key,
- const struct GNUNET_HashCode *slave_key,
+ (*membership_store) (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
int did_join,
uint64_t announced_at,
uint64_t effective_since,
@@ -71,7 +71,7 @@
* Test if a member was admitted to the channel at the given message ID.
*
* @see GNUNET_PSYCSTORE_membership_test()
- *
+ *
* @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
* #GNUNET_SYSERR if there was en error.
*/
@@ -79,41 +79,42 @@
(*membership_test) (void *cls,
const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
- uint64_t message_id,
- uint64_t group_generation);
+ uint64_t message_id);
/**
* Store a message fragment sent to a channel.
*
* @see GNUNET_PSYCSTORE_fragment_store()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
(*fragment_store) (void *cls,
const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- const struct GNUNET_MULTICAST_MessageHeader *message);
+ const struct GNUNET_MULTICAST_MessageHeader *message,
+ uint32_t psycstore_flags);
/**
* Set additional flags for a given message.
*
+ * They are OR'd with any existing flags set.
+ *
* @param message_id ID of the message.
- * @param flags Flags to add.
- *
+ * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags.
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
- (*fragment_add_flags) (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t message_id,
- uint64_t multicast_flags,
- uint64_t psyc_flags);
+ (*message_add_flags) (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t message_id,
+ uint64_t psycstore_flags);
/**
* Retrieve a message fragment by fragment ID.
*
* @see GNUNET_PSYCSTORE_fragment_get()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
@@ -127,7 +128,7 @@
* Retrieve all fragments of a message.
*
* @see GNUNET_PSYCSTORE_message_get()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
@@ -142,7 +143,7 @@
* offset.
*
* @see GNUNET_PSYCSTORE_message_get_fragment()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
@@ -157,7 +158,7 @@
* Retrieve latest values of counters for a channel master.
*
* @see GNUNET_PSYCSTORE_counters_get_master()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
@@ -168,10 +169,10 @@
uint64_t *group_generation);
/**
- * Retrieve latest values of counters for a channel slave.
+ * Retrieve latest values of counters for a channel slave.
*
* @see GNUNET_PSYCSTORE_counters_get_slave()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
@@ -183,27 +184,66 @@
* Set a state variable to the given value.
*
* @see GNUNET_PSYCSTORE_state_modify()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
- (*state_set) (struct GNUNET_PSYCSTORE_Handle *h,
+ (*state_set) (void *cls,
const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
const char *name,
- size_t value_size,
- const void *value);
+ const void *value,
+ size_t value_size);
+
/**
- * Retrieve a state variable by name.
+ * Reset the state of a channel.
*
- * @param name Name of the variable to retrieve.
- * @param[out] value_size Size of value.
- * @param[out] value Returned value.
- *
+ * Delete all state variables stored for the given channel.
+ *
+ * @see GNUNET_PSYCSTORE_state_reset()
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
- (*state_get) (struct GNUNET_PSYCSTORE_Handle *h,
+ (*state_reset) (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key);
+
+ /**
+ * Update signed state values from the current ones.
+ *
+ * Sets value_signed = value_current for each variable for the given channel.
+ */
+ int
+ (*state_update_signed) (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey
*channel_key);
+
+ /**
+ * Update signed values of state variables in the state store.
+ *
+ * @param h Handle for the PSYCstore.
+ * @param channel_key The channel we are interested in.
+ * @param message_id Message ID that contained the state @a hash.
+ * @param hash Hash of the serialized full state.
+ * @param rcb Callback to call with the result of the operation.
+ * @param rcb_cls Closure for the callback.
+ *
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+ int
+ (*state_hash_update) (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t message_id,
+ const struct GNUNET_HashCode *hash,
+ GNUNET_PSYCSTORE_ResultCallback rcb,
+ void *rcb_cls);
+
+ /**
+ * Retrieve a state variable by name (exact match).
+ *
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+ int
+ (*state_get) (void *cls,
const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
const char *name,
GNUNET_PSYCSTORE_StateCallback cb,
@@ -213,16 +253,28 @@
* Retrieve all state variables for a channel with the given prefix.
*
* @see GNUNET_PSYCSTORE_state_get_all()
- *
+ *
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
int
- (*state_get_all) (struct GNUNET_PSYCSTORE_Handle *h,
+ (*state_get_all) (void *cls,
const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
const char *name,
GNUNET_PSYCSTORE_StateCallback cb,
void *cb_cls);
+
+ /**
+ * Retrieve all signed state variables for a channel.
+ *
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+ int
+ (*state_get_signed) (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ GNUNET_PSYCSTORE_StateCallback cb,
+ void *cb_cls);
+
};
Modified: gnunet/src/include/gnunet_psycstore_service.h
===================================================================
--- gnunet/src/include/gnunet_psycstore_service.h 2013-09-03 19:16:43 UTC
(rev 28973)
+++ gnunet/src/include/gnunet_psycstore_service.h 2013-09-03 22:33:21 UTC
(rev 28974)
@@ -45,6 +45,28 @@
*/
#define GNUNET_PSYCSTORE_VERSION 0x00000000
+/**
+ * Flags for stored messages.
+ */
+enum GNUNET_PSYCSTORE_MessageFlags
+{
+ /**
+ * The message contains state modifiers.
+ */
+ GNUNET_PSYCSTORE_MESSAGE_STATE = 1 << 0,
+
+ /**
+ * The state modifiers have been applied to the state store.
+ */
+ GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED = 1 << 1,
+
+ /**
+ * The message contains a state hash.
+ */
+ GNUNET_PSYCSTORE_MESSAGE_STATE_HASH = 1 << 2
+};
+
+
/**
* Handle for a PSYCstore
*/
@@ -157,6 +179,8 @@
* @param h Handle for the PSYCstore.
* @param channel_key The channel the message belongs to.
* @param message Message to store.
+ * @param psycstore_flags Flags indicating whether the PSYC message contains
+ * state modifiers.
* @param rcb Callback to call with the result of the operation.
* @param rcb_cls Closure for the callback.
*
@@ -166,6 +190,7 @@
GNUNET_PSYCSTORE_fragment_store (struct GNUNET_PSYCSTORE_Handle *h,
const struct GNUNET_CRYPTO_EccPublicKey
*channel_key,
const struct GNUNET_MULTICAST_MessageHeader
*message,
+ uint32_t psycstore_flags,
GNUNET_PSYCSTORE_ResultCallback rcb,
void *rcb_cls);
@@ -177,12 +202,15 @@
* @param cls Closure.
* @param message The retrieved message fragment. A NULL value indicates that
* there are no more results to be returned.
- * @param flags Message flags indicating fragmentation status.
+ * @param flags Flags stored with the message.
+ *
+ * @return #GNUNET_NO to stop calling this callback with further fragments,
+ * #GNUNET_YES to continue.
*/
-typedef void
+typedef int
(*GNUNET_PSYCSTORE_FragmentCallback) (void *cls,
- const struct
GNUNET_MULTICAST_MessageHeader *message,
- enum GNUNET_PSYC_MessageFlags flags);
+ struct GNUNET_MULTICAST_MessageHeader
*message,
+ enum GNUNET_PSYCSTORE_MessageFlags
flags);
/**
@@ -224,7 +252,8 @@
/**
- * Retrieve a fragment of message specified by its message ID and fragment
offset.
+ * Retrieve a fragment of message specified by its message ID and fragment
+ * offset.
*
* @param h Handle for the PSYCstore.
* @param channel_key The channel we are interested in.
@@ -267,7 +296,8 @@
* @see GNUNET_PSYCSTORE_counters_get_slave()
*
* @param cls Closure.
- * @param max_state_msg_id Latest message ID containing state modifiers that
was applied to the state store. Used for the state sync process.
+ * @param max_state_msg_id Latest message ID containing state modifiers that
was
+ * applied to the state store. Used for the state sync process.
*/
typedef void
(*GNUNET_PSYCSTORE_SlaveCountersCallback) (void *cls,
@@ -343,6 +373,26 @@
/**
+ * Reset the state of a channel.
+ *
+ * Delete all state variables stored for the given channel.
+ *
+ * @param h Handle for the PSYCstore.
+ * @param channel_key The channel we are interested in.
+ * @param rcb Callback to call with the result of the operation.
+ * @param rcb_cls Closure for the callback.
+ *
+ * @return Handle that can be used to cancel the operation.
+ */
+struct GNUNET_PSYCSTORE_Handle *
+GNUNET_PSYCSTORE_state_reset (struct GNUNET_PSYCSTORE_Handle *h,
+ const struct GNUNET_CRYPTO_EccPublicKey
+ *channel_key,
+ GNUNET_PSYCSTORE_ResultCallback rcb,
+ void *rcb_cls);
+
+
+/**
* Update signed values of state variables in the state store.
*
* @param h Handle for the PSYCstore.
@@ -368,15 +418,17 @@
* @param cls Closure.
* @param name Name of the state variable. A NULL value indicates that there
are no more
* state variables to be returned.
+ * @param value Value of the state variable.
* @param value_size Number of bytes in @a value.
- * @param value Value of the state variable.
-t *
+ *
+ * @return #GNUNET_NO to stop calling this callback with further variables,
+ * #GNUNET_YES to continue.
*/
-typedef void
+typedef int
(*GNUNET_PSYCSTORE_StateCallback) (void *cls,
const char *name,
- size_t value_size,
- const void *value);
+ const void *value,
+ size_t value_size);
/**
@@ -420,10 +472,10 @@
/**
* Cancel an operation.
*
- * @param oh Handle for the operation to cancel.
+ * @param op Handle for the operation to cancel.
*/
void
-GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle
*oh);
+GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle
*op);
Modified: gnunet/src/include/gnunet_social_service.h
===================================================================
--- gnunet/src/include/gnunet_social_service.h 2013-09-03 19:16:43 UTC (rev
28973)
+++ gnunet/src/include/gnunet_social_service.h 2013-09-03 22:33:21 UTC (rev
28974)
@@ -83,21 +83,22 @@
* @param modifier_count Number of elements in the @a modifiers array.
* @param modifiers Modifiers present in the message. FIXME: use environment
instead?
* @param data_offset Byte offset of @a data in the overall data of the method.
- * @param data_size Number of bytes in @a data.
* @param data Data stream given to the method (might not be zero-terminated
* if data is binary).
+ * @param data_size Number of bytes in @a data.
* @param flags Message flags indicating fragmentation status.
*/
-typedef int (*GNUNET_SOCIAL_Method)(void *cls,
- struct GNUNET_SOCIAL_Nym *nym,
- const char *full_method_name,
- uint64_t message_id,
- size_t modifier_count,
- GNUNET_PSYC_Modifier *modifiers,
- uint64_t data_offset,
- size_t data_size,
- const void *data,
- enum GNUNET_PSYC_MessageFlags flags);
+typedef int
+(*GNUNET_SOCIAL_Method) (void *cls,
+ struct GNUNET_SOCIAL_Nym *nym,
+ const char *full_method_name,
+ uint64_t message_id,
+ size_t modifier_count,
+ GNUNET_PSYC_Modifier *modifiers,
+ uint64_t data_offset,
+ const void *data,
+ size_t data_size,
+ enum GNUNET_PSYC_MessageFlags flags);
/**
@@ -164,16 +165,17 @@
* @param method_name Method name in the entry request.
* @param variable_count Number of elements in the @a variables array.
* @param variables Variables present in the message.
+ * @param data Payload given on enter (e.g. a password).
* @param data_size Number of bytes in @a data.
- * @param data Payload given on enter (e.g. a password).
*/
-typedef void (*GNUNET_SOCIAL_AnswerDoorCallback)(void *cls,
- struct GNUNET_SOCIAL_Nym *nym,
- size_t variable_count,
- const char *method_name,
- GNUNET_PSYC_Modifier
*variables,
- size_t data_size,
- const void *data);
+typedef void
+(*GNUNET_SOCIAL_AnswerDoorCallback) (void *cls,
+ struct GNUNET_SOCIAL_Nym *nym,
+ size_t variable_count,
+ const char *method_name,
+ GNUNET_PSYC_Modifier *variables,
+ const void *data,
+ size_t data_size);
/**
@@ -187,10 +189,11 @@
* @param variable_count Number of elements in the @a variables array.
* @param variables Variables present in the message.
*/
-typedef void (*GNUNET_SOCIAL_FarewellCallback)(void *cls,
- struct GNUNET_SOCIAL_Nym *nym,
- size_t variable_count,
- GNUNET_PSYC_Modifier
*variables);
+typedef void
+(*GNUNET_SOCIAL_FarewellCallback) (void *cls,
+ struct GNUNET_SOCIAL_Nym *nym,
+ size_t variable_count,
+ GNUNET_PSYC_Modifier *variables);
/**
@@ -258,16 +261,16 @@
* @param nym Handle for the entity that wanted to enter.
* @param method_name Method name for the rejection message.
* @param env Environment containing variables for the message, or NULL.
+ * @param data Data for the rejection message to send back.
* @param data_size Number of bytes in @a data for method.
- * @param data Data for the rejection message to send back.
*/
void
GNUNET_SOCIAL_home_reject_entry (struct GNUNET_SOCIAL_Home *home,
struct GNUNET_SOCIAL_Nym *nym,
const char *method_name,
const struct GNUNET_ENV_Environment *env,
- size_t data_size,
- const void *data);
+ const void *data,
+ size_t data_size);
/**
@@ -403,8 +406,8 @@
* pseudonym's place directly.
* @param method_name Method name for the message.
* @param env Environment containing variables for the message, or NULL.
+ * @param data Payload for the message to give to the enter callback.
* @param data_size Number of bytes in @a data.
- * @param data Payload for the message to give to the enter callback.
* @param slicer Slicer to use for processing incoming requests from guests.
* @return NULL on errors, otherwise handle to the place.
*/
@@ -414,8 +417,8 @@
char *address,
const char *method_name,
const struct GNUNET_ENV_Environment *env,
+ const void *data,
size_t data_size,
- const void *data,
struct GNUNET_SOCIAL_Slicer *slicer);
/**
@@ -429,8 +432,8 @@
* @param relays Relays for the underlying multicast group.
* @param method_name Method name for the message.
* @param env Environment containing variables for the message, or NULL.
+ * @param data Payload for the message to give to the enter callback.
* @param data_size Number of bytes in @a data.
- * @param data Payload for the message to give to the enter callback.
* @param slicer Slicer to use for processing incoming requests from guests.
* @return NULL on errors, otherwise handle to the place.
*/
@@ -443,8 +446,8 @@
struct GNUNET_PeerIdentity *relays,
const char *method_name,
const struct GNUNET_ENV_Environment *env,
+ const void *data,
size_t data_size,
- const void *data,
struct GNUNET_SOCIAL_Slicer *slicer);
Modified: gnunet/src/psycstore/Makefile.am
===================================================================
--- gnunet/src/psycstore/Makefile.am 2013-09-03 19:16:43 UTC (rev 28973)
+++ gnunet/src/psycstore/Makefile.am 2013-09-03 22:33:21 UTC (rev 28974)
@@ -22,7 +22,7 @@
if HAVE_SQLITE
SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la
if HAVE_TESTING
-#SQLITE_TESTS = test_plugin_psycstore_sqlite
+SQLITE_TESTS = test_plugin_psycstore_sqlite
endif
endif
@@ -99,3 +99,14 @@
test_psycstore.conf
+test_plugin_psycstore_sqlite_SOURCES = \
+ test_plugin_psycstore.c
+test_plugin_psycstore_sqlite_LDADD = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+test_plugin_psycstore_postgres_SOURCES = \
+ test_plugin_psycstore.c
+test_plugin_psycstore_postgres_LDADD = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/util/libgnunetutil.la
Modified: gnunet/src/psycstore/gnunet-service-psycstore.c
===================================================================
--- gnunet/src/psycstore/gnunet-service-psycstore.c 2013-09-03 19:16:43 UTC
(rev 28973)
+++ gnunet/src/psycstore/gnunet-service-psycstore.c 2013-09-03 22:33:21 UTC
(rev 28974)
@@ -101,27 +101,72 @@
uint32_t result_code,
const char *emsg)
{
- struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm;
+ struct ResultCodeMessage *rcm;
size_t elen;
if (NULL == emsg)
elen = 0;
else
elen = strlen (emsg) + 1;
- rcm = GNUNET_malloc (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) +
elen);
+ rcm = GNUNET_malloc (sizeof (struct ResultCodeMessage) + elen);
rcm->header.type = htons (GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE);
- rcm->header.size = htons (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)
+ elen);
+ rcm->header.size = htons (sizeof (struct ResultCodeMessage) + elen);
rcm->result_code = htonl (result_code);
memcpy (&rcm[1], emsg, elen);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending result %d (%s) to client\n",
(int) result_code,
emsg);
- GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header,
GNUNET_NO);
+ GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header,
+ GNUNET_NO);
GNUNET_free (rcm);
}
+static void
+handle_membership_store (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct MembershipStoreMessage *msg =
+ (const struct MembershipStoreMessage *) message;
+
+ int res = db->membership_store (db->cls, msg->channel_key, msg->slave_key,
+ msg->did_join, msg->announced_at,
+ msg->effective_since, msg->group_generation);
+
+ if (res != GNUNET_OK)
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to store membership information!\n"));
+
+ send_result_code (client, res, NULL);
+}
+
+
+static void
+handle_membership_test (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct MembershipTestMessage *msg =
+ (const struct MembershipTestMessage *) message;
+
+ int res = db->membership_test (db->cls, msg->channel_key, msg->slave_key,
+ msg->message_id);
+ switch (res)
+ {
+ case GNUNET_YES:
+ case GNUNET_NO:
+ break;
+ default:
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to test membership!\n"));
+ }
+
+ send_result_code (client, res, NULL);
+}
+
+
/**
* Handle PSYCstore clients.
*
@@ -135,6 +180,12 @@
const struct GNUNET_CONFIGURATION_Handle *c)
{
static const struct GNUNET_SERVER_MessageHandler handlers[] = {
+ {&handle_membership_store, NULL,
+ GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_STORE,
+ sizeof (struct MembershipStoreMessage)},
+ {&handle_membership_test, NULL,
+ GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_TEST,
+ sizeof (struct MembershipTestMessage)},
{NULL, NULL, 0, 0}
};
Modified: gnunet/src/psycstore/plugin_psycstore_sqlite.c
===================================================================
--- gnunet/src/psycstore/plugin_psycstore_sqlite.c 2013-09-03 19:16:43 UTC
(rev 28973)
+++ gnunet/src/psycstore/plugin_psycstore_sqlite.c 2013-09-03 22:33:21 UTC
(rev 28974)
@@ -25,9 +25,16 @@
* @author Christian Grothoff
*/
+/*
+ * FIXME: SQLite3 only supports signed 64-bit integers natively,
+ * thus it can only store 63 bits of the uint64_t's.
+ */
+
#include "platform.h"
#include "gnunet_psycstore_plugin.h"
#include "gnunet_psycstore_service.h"
+#include "gnunet_multicast_service.h"
+#include "gnunet_crypto_lib.h"
#include "psycstore.h"
#include <sqlite3.h>
@@ -43,13 +50,14 @@
*/
#define BUSY_TIMEOUT_MS 1000
+#define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING
/**
* Log an error message at log-level 'level' that indicates
* a failure of the command 'cmd' on file 'filename'
* with the message given by strerror(errno).
*/
-#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)
+#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)
#define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__)
@@ -100,9 +108,9 @@
sqlite3_stmt *insert_fragment;
/**
- * Precompiled SQL for fragment_add_flags()
+ * Precompiled SQL for message_add_flags()
*/
- sqlite3_stmt *update_fragment_flags;
+ sqlite3_stmt *update_message_flags;
/**
* Precompiled SQL for fragment_get()
@@ -122,12 +130,12 @@
/**
* Precompiled SQL for counters_get_master()
*/
- sqlite3_stmt *select_master_counters;
+ sqlite3_stmt *select_counters_master;
/**
* Precompiled SQL for counters_get_slave()
*/
- sqlite3_stmt *select_slave_counters;
+ sqlite3_stmt *select_counters_slave;
/**
@@ -136,11 +144,6 @@
sqlite3_stmt *insert_state_current;
/**
- * Precompiled SQL for state_set()
- */
- sqlite3_stmt *update_state_current;
-
- /**
* Precompiled SQL for state_set_signed()
*/
sqlite3_stmt *update_state_signed;
@@ -166,6 +169,11 @@
sqlite3_stmt *delete_state_sync;
/**
+ * Precompiled SQL for state_get_signed()
+ */
+ sqlite3_stmt *select_state_signed;
+
+ /**
* Precompiled SQL for state_get()
*/
sqlite3_stmt *select_state_one;
@@ -177,7 +185,16 @@
};
+#if DEBUG_PSYCSTORE
+static void
+sql_trace (void *cls, const char *sql)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "SQL query:\n%s\n", sql);
+}
+
+#endif
+
/**
* @brief Prepare a SQL statement
*
@@ -208,8 +225,7 @@
* @brief Prepare a SQL statement
*
* @param dbh handle to the database
- * @param zSql SQL statement, UTF-8 encoded
- * @param ppStmt set to the prepared statement
+ * @param sql SQL statement, UTF-8 encoded
* @return 0 on success
*/
static int
@@ -262,7 +278,7 @@
plugin->fn = filename;
/* Open database and precompile statements */
- if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
+ if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
_("Unable to initialize SQLite: %s.\n"),
@@ -270,6 +286,10 @@
return GNUNET_SYSERR;
}
+#if DEBUG_PSYCSTORE
+ sqlite3_trace (plugin->dbh, &sql_trace, NULL);
+#endif
+
sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL");
sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
@@ -284,62 +304,62 @@
/* Create tables */
sql_exec (plugin->dbh,
- "CREATE TABLE IF NOT EXISTS channels ("
- " id INTEGER PRIMARY KEY,"
- " pub_key BLOB UNIQUE"
+ "CREATE TABLE IF NOT EXISTS channels (\n"
+ " id INTEGER PRIMARY KEY,\n"
+ " pub_key BLOB UNIQUE\n"
");");
sql_exec (plugin->dbh,
- "CREATE TABLE IF NOT EXISTS slaves ("
- " id INTEGER PRIMARY KEY,"
- " pub_key BLOB UNIQUE"
+ "CREATE TABLE IF NOT EXISTS slaves (\n"
+ " id INTEGER PRIMARY KEY,\n"
+ " pub_key BLOB UNIQUE\n"
");");
sql_exec (plugin->dbh,
- "CREATE TABLE IF NOT EXISTS membership ("
- " channel_id INTEGER NOT NULL REFERENCES channels(id),"
- " slave_id INTEGER NOT NULL REFERENCES slaves(id),"
- " did_join INTEGER NOT NULL,"
- " announced_at INTEGER NOT NULL,"
- " effective_since INTEGER NOT NULL,"
- " group_generation INTEGER NOT NULL"
+ "CREATE TABLE IF NOT EXISTS membership (\n"
+ " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+ " slave_id INTEGER NOT NULL REFERENCES slaves(id),\n"
+ " did_join INTEGER NOT NULL,\n"
+ " announced_at INTEGER NOT NULL,\n"
+ " effective_since INTEGER NOT NULL,\n"
+ " group_generation INTEGER NOT NULL\n"
");");
sql_exec (plugin->dbh,
"CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id "
"ON membership (channel_id, slave_id);");
sql_exec (plugin->dbh,
- "CREATE TABLE IF NOT EXISTS messages ("
- " channel_id INTEGER NOT NULL,"
- " hop_counter INTEGER NOT NULL,"
- " signature BLOB,"
- " purpose BLOB,"
- " fragment_id INTEGER NOT NULL,"
- " fragment_offset INTEGER NOT NULL,"
- " message_id INTEGER NOT NULL,"
- " group_generation INTEGER NOT NULL,"
- " multicast_flags INTEGER NOT NULL,"
- " psyc_flags INTEGER NOT NULL,"
- " data BLOB,"
- " PRIMARY KEY (channel_id, fragment_id),"
- " UNIQUE (channel_id, message_id, fragment_offset)"
+ "CREATE TABLE IF NOT EXISTS messages (\n"
+ " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+ " hop_counter INTEGER NOT NULL,\n"
+ " signature BLOB,\n"
+ " purpose BLOB,\n"
+ " fragment_id INTEGER NOT NULL,\n"
+ " fragment_offset INTEGER NOT NULL,\n"
+ " message_id INTEGER NOT NULL,\n"
+ " group_generation INTEGER NOT NULL,\n"
+ " multicast_flags INTEGER NOT NULL,\n"
+ " psycstore_flags INTEGER NOT NULL,\n"
+ " data BLOB,\n"
+ " PRIMARY KEY (channel_id, fragment_id),\n"
+ " UNIQUE (channel_id, message_id, fragment_offset)\n"
");");
sql_exec (plugin->dbh,
- "CREATE TABLE IF NOT EXISTS state ("
- " channel_id INTEGER NOT NULL,"
- " name TEXT NOT NULL,"
- " value_current BLOB, "
- " value_signed BLOB, "
- " PRIMARY KEY (channel_id, name)"
+ "CREATE TABLE IF NOT EXISTS state (\n"
+ " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+ " name TEXT NOT NULL,\n"
+ " value_current BLOB,\n"
+ " value_signed BLOB,\n"
+ " PRIMARY KEY (channel_id, name)\n"
");");
sql_exec (plugin->dbh,
- "CREATE TABLE IF NOT EXISTS state_sync ("
- " channel_id INTEGER NOT NULL,"
- " name TEXT NOT NULL,"
- " value BLOB, "
- " PRIMARY KEY (channel_id, name)"
+ "CREATE TABLE IF NOT EXISTS state_sync (\n"
+ " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+ " name TEXT NOT NULL,\n"
+ " value BLOB,\n"
+ " PRIMARY KEY (channel_id, name)\n"
");");
/* Prepare statements */
@@ -353,132 +373,143 @@
&plugin->insert_slave_key);
sql_prepare (plugin->dbh,
- "INSERT INTO membership "
- " (channel_id, slave_id, did_join, announced_at, "
- " effective_since, group_generation) "
- "VALUES ((SELECT id FROM channels WHERE pub_key = ?), "
- " (SELECT id FROM slaves WHERE pub_key = ?), "
+ "INSERT INTO membership\n"
+ " (channel_id, slave_id, did_join, announced_at,\n"
+ " effective_since, group_generation)\n"
+ "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n"
+ " (SELECT id FROM slaves WHERE pub_key = ?),\n"
" ?, ?, ?, ?);",
&plugin->insert_membership);
sql_prepare (plugin->dbh,
- "SELECT did_join FROM membership "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
- " AND slave_id = ? AND effective_since <= ? "
+ "SELECT did_join FROM membership\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
+ " AND slave_id = (SELECT id FROM slaves WHERE pub_key =
?)\n"
+ " AND effective_since <= ? AND did_join = 1\n"
"ORDER BY announced_at DESC LIMIT 1;",
&plugin->select_membership);
sql_prepare (plugin->dbh,
- "INSERT INTO messages "
- " (channel_id, hop_counter, signature, purpose, "
- " fragment_id, fragment_offset, message_id, "
- " group_generation, multicast_flags, psyc_flags, data) "
- "VALUES ((SELECT id FROM channels WHERE pub_key = ?), "
+ "INSERT INTO messages\n"
+ " (channel_id, hop_counter, signature, purpose,\n"
+ " fragment_id, fragment_offset, message_id,\n"
+ " group_generation, multicast_flags, psycstore_flags, data)\n"
+ "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n"
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
&plugin->insert_fragment);
sql_prepare (plugin->dbh,
- "UPDATE messages "
- "SET multicast_flags = multicast_flags | ?, "
- " psyc_flags = psyc_flags | ? "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
- " AND message_id = ?;",
- &plugin->update_fragment_flags);
+ "UPDATE messages\n"
+ "SET psycstore_flags = psycstore_flags | ?\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
+ " AND message_id = ? AND fragment_offset = 0;",
+ &plugin->update_message_flags);
sql_prepare (plugin->dbh,
- "SELECT hop_counter, signature, purpose, "
- " fragment_offset, message_id, group_generation, "
- " multicast_flags, psyc_flags, data "
- "FROM messages "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
+ "SELECT hop_counter, signature, purpose, fragment_id,\n"
+ " fragment_offset, message_id, group_generation,\n"
+ " multicast_flags, psycstore_flags, data\n"
+ "FROM messages\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
" AND fragment_id = ?;",
&plugin->select_fragment);
sql_prepare (plugin->dbh,
- "SELECT hop_counter, signature, purpose, "
- " fragment_id, fragment_offset, group_generation, "
- " multicast_flags, psyc_flags, data "
- "FROM messages "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
+ "SELECT hop_counter, signature, purpose, fragment_id,\n"
+ " fragment_offset, message_id, group_generation,\n"
+ " multicast_flags, psycstore_flags, data\n"
+ "FROM messages\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
" AND message_id = ?;",
&plugin->select_message);
sql_prepare (plugin->dbh,
- "SELECT hop_counter, signature, purpose, "
- " fragment_id, message_id, group_generation, "
- " multicast_flags, psyc_flags, data "
- "FROM messages "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
+ "SELECT hop_counter, signature, purpose, fragment_id,\n"
+ " fragment_offset, message_id, group_generation,\n"
+ " multicast_flags, psycstore_flags, data\n"
+ "FROM messages\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
" AND message_id = ? AND fragment_offset = ?;",
&plugin->select_message_fragment);
sql_prepare (plugin->dbh,
- "SELECT max(fragment_id), max(message_id),
max(group_generation) "
- "FROM messages "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?);",
- &plugin->select_master_counters);
+ "SELECT fragment_id, message_id, group_generation\n"
+ "FROM messages\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
+ "ORDER BY fragment_id DESC LIMIT 1;",
+ &plugin->select_counters_master);
sql_prepare (plugin->dbh,
- "SELECT max(message_id) "
- "FROM messages "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
- " AND psyc_flags & ?;",
- &plugin->select_slave_counters);
+ "SELECT message_id\n"
+ "FROM messages\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
+ " AND psycstore_flags & ?\n"
+ "ORDER BY message_id DESC LIMIT 1",
+ &plugin->select_counters_slave);
sql_prepare (plugin->dbh,
- "INSERT OR REPLACE INTO state (channel_id, name, value_current)
"
- "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
+ "INSERT OR REPLACE INTO state\n"
+ " (channel_id, name, value_current, value_signed)\n"
+ "SELECT new.channel_id, new.name,\n"
+ " new.value_current, old.value_signed\n"
+ "FROM (SELECT (SELECT id FROM channels WHERE pub_key = ?)\n"
+ " AS channel_id,\n"
+ " ? AS name, ? AS value_current) AS new\n"
+ "LEFT JOIN (SELECT channel_id, name, value_signed\n"
+ " FROM state) AS old\n"
+ "ON new.channel_id = old.channel_id AND new.name = old.name;",
&plugin->insert_state_current);
sql_prepare (plugin->dbh,
- "UPDATE state "
- "SET value_current = ? "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
- " AND name = ?;",
- &plugin->update_state_current);
-
- sql_prepare (plugin->dbh,
- "UPDATE state "
- "SET value_signed = value_current "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
",
+ "UPDATE state\n"
+ "SET value_signed = value_current\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?);",
&plugin->update_state_signed);
sql_prepare (plugin->dbh,
- "INSERT INTO state_sync (channel_id, name, value) "
+ "INSERT INTO state_sync (channel_id, name, value)\n"
"VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
&plugin->insert_state_sync);
sql_prepare (plugin->dbh,
- "DELETE FROM state "
+ "DELETE FROM state\n"
"WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?);",
&plugin->delete_state);
sql_prepare (plugin->dbh,
- "INSERT INTO state "
- " (channel_id, name, value_current, value_signed) "
- "SELECT channel_id, name, value, value "
- "FROM state_sync "
+ "INSERT INTO state\n"
+ " (channel_id, name, value_current, value_signed)\n"
+ "SELECT channel_id, name, value, value\n"
+ "FROM state_sync\n"
"WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?);",
&plugin->insert_state_from_sync);
sql_prepare (plugin->dbh,
- "DELETE FROM state_sync "
+ "DELETE FROM state_sync\n"
"WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?);",
&plugin->delete_state_sync);
sql_prepare (plugin->dbh,
- "SELECT value_current "
- "FROM state "
- "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)
"
+ "SELECT value_current\n"
+ "FROM state\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
" AND name = ?;",
&plugin->select_state_one);
sql_prepare (plugin->dbh,
- "SELECT value_current "
- "FROM state "
- "WHERE name LIKE ? OR name LIKE ?;",
+ "SELECT name, value_current\n"
+ "FROM state\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key =
?)\n"
+ " AND name = ? OR name LIKE ?;",
&plugin->select_state_prefix);
+ sql_prepare (plugin->dbh,
+ "SELECT name, value_signed\n"
+ "FROM state\n"
+ "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)"
+ " AND value_signed IS NOT NULL;",
+ &plugin->select_state_signed);
+
return GNUNET_OK;
}
@@ -509,8 +540,8 @@
if (NULL != plugin->insert_fragment)
sqlite3_finalize (plugin->insert_fragment);
- if (NULL != plugin->update_fragment_flags)
- sqlite3_finalize (plugin->update_fragment_flags);
+ if (NULL != plugin->update_message_flags)
+ sqlite3_finalize (plugin->update_message_flags);
if (NULL != plugin->select_fragment)
sqlite3_finalize (plugin->select_fragment);
@@ -521,18 +552,15 @@
if (NULL != plugin->select_message_fragment)
sqlite3_finalize (plugin->select_message_fragment);
- if (NULL != plugin->select_master_counters)
- sqlite3_finalize (plugin->select_master_counters);
+ if (NULL != plugin->select_counters_master)
+ sqlite3_finalize (plugin->select_counters_master);
- if (NULL != plugin->select_slave_counters)
- sqlite3_finalize (plugin->select_slave_counters);
+ if (NULL != plugin->select_counters_slave)
+ sqlite3_finalize (plugin->select_counters_slave);
if (NULL != plugin->insert_state_current)
sqlite3_finalize (plugin->insert_state_current);
- if (NULL != plugin->update_state_current)
- sqlite3_finalize (plugin->update_state_current);
-
if (NULL != plugin->update_state_signed)
sqlite3_finalize (plugin->update_state_signed);
@@ -579,6 +607,65 @@
}
+static int
+channel_key_store (struct Plugin *plugin,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key)
+{
+ sqlite3_stmt *stmt = plugin->insert_channel_key;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_channel_key (bind)");
+ }
+ else if (SQLITE_DONE != sqlite3_step (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_channel_key (step)");
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_channel_key (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
+}
+
+
+static int
+slave_key_store (struct Plugin *plugin,
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key)
+{
+ sqlite3_stmt *stmt = plugin->insert_slave_key;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, slave_key,
+ sizeof (*slave_key), SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_slave_key (bind)");
+ }
+ else if (SQLITE_DONE != sqlite3_step (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_slave_key (step)");
+ }
+
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_slave_key (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
+}
+
+
/**
* Store join/leave events for a PSYC channel in order to be able to answer
* membership test queries later.
@@ -587,17 +674,56 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_membership_store
- (void *cls,
- const struct GNUNET_HashCode *channel_key,
- const struct GNUNET_HashCode *slave_key,
- int did_join,
- uint64_t announced_at,
- uint64_t effective_since,
- uint64_t group_generation) {
+static int
+membership_store (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+ int did_join,
+ uint64_t announced_at,
+ uint64_t effective_since,
+ uint64_t group_generation)
+{
+ if (announced_at > INT64_MAX ||
+ effective_since > INT64_MAX ||
+ group_generation > INT64_MAX)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->insert_membership;
+ if (GNUNET_OK != channel_key_store (plugin, channel_key) ||
+ GNUNET_OK != slave_key_store (plugin, slave_key))
+ return GNUNET_SYSERR;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key,
+ sizeof (*slave_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int (stmt, 3, did_join) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 4, announced_at) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 5, effective_since) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 6, group_generation))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_membership (bind)");
+ }
+ else if (SQLITE_DONE != sqlite3_step (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_membership (step)");
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_membership (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
}
/**
@@ -608,14 +734,44 @@
* @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
* #GNUNET_SYSERR if there was en error.
*/
-int
-libgnunet_plugin_psycstore_sqlite_membership_test
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
- uint64_t message_id,
- uint64_t group_generation) {
+static int
+membership_test (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+ uint64_t message_id)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->select_membership;
+ int ret = GNUNET_SYSERR;
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key,
+ sizeof (*slave_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_membership (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = GNUNET_YES;
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_membership (reset)");
+ }
+
+ return ret;
}
/**
@@ -625,32 +781,143 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_fragment_store
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- const struct GNUNET_MULTICAST_MessageHeader *message) {
+static int
+fragment_store (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const struct GNUNET_MULTICAST_MessageHeader *msg,
+ uint32_t psycstore_flags)
+{
+ if (msg->fragment_id > INT64_MAX ||
+ msg->fragment_offset > INT64_MAX ||
+ msg->message_id > INT64_MAX ||
+ msg->group_generation > INT64_MAX)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->insert_fragment;
+
+ if (GNUNET_OK != channel_key_store (plugin, channel_key))
+ return GNUNET_SYSERR;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 2, msg->hop_counter ) ||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 3, (const void *) &msg->signature,
+ sizeof (msg->signature), SQLITE_STATIC)
||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 4, (const void *) &msg->purpose,
+ sizeof (msg->purpose), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 5, msg->fragment_id) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 6, msg->fragment_offset) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 7, msg->message_id) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 8, msg->group_generation) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 9, msg->flags) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 10, psycstore_flags) ||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 11, (const void *) &msg[1],
+ ntohs (msg->header.size) - sizeof (*msg),
+ SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_fragment (bind)");
+ }
+ else if (SQLITE_DONE != sqlite3_step (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_fragment (step)");
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_fragment (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
}
/**
* Set additional flags for a given message.
*
+ * They are OR'd with any existing flags set.
+ *
+ * @param plugin Plugin handle.
+ * @param channel_key Public key of the channel.
* @param message_id ID of the message.
- * @param flags Flags to add.
+ * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags.
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_fragment_add_flags
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t message_id,
- uint64_t multicast_flags,
- uint64_t psyc_flags) {
+static int
+message_add_flags (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t message_id,
+ uint64_t psycstore_flags)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->update_message_flags;
+ int ret = GNUNET_SYSERR;
+ if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, psycstore_flags) ||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "update_message_flags (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "update_message_flags (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "update_message_flags (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return ret;
}
+static int
+fragment_row (sqlite3_stmt *stmt, GNUNET_PSYCSTORE_FragmentCallback cb,
+ void *cb_cls)
+{
+ int data_size = sqlite3_column_bytes (stmt, 9);
+ struct GNUNET_MULTICAST_MessageHeader *msg
+ = GNUNET_malloc (sizeof (*msg) + data_size);
+
+ msg->header.size = htons (sizeof (*msg) + data_size);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
+ msg->hop_counter = (uint32_t) sqlite3_column_int64 (stmt, 0);
+ memcpy (&msg->signature,
+ sqlite3_column_blob (stmt, 1),
+ sqlite3_column_bytes (stmt, 1));
+ memcpy (&msg->purpose,
+ sqlite3_column_blob (stmt, 2),
+ sqlite3_column_bytes (stmt, 2));
+ msg->fragment_id = sqlite3_column_int64 (stmt, 3);
+ msg->fragment_offset = sqlite3_column_int64 (stmt, 4);
+ msg->message_id = sqlite3_column_int64 (stmt, 5);
+ msg->group_generation = sqlite3_column_int64 (stmt, 6);
+ msg->flags = sqlite3_column_int64 (stmt, 7);
+ memcpy (&msg[1], sqlite3_column_blob (stmt, 9), data_size);
+
+ return cb (cb_cls, (void *) msg, sqlite3_column_int64 (stmt, 8));
+}
+
/**
* Retrieve a message fragment by fragment ID.
*
@@ -658,14 +925,49 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_fragment_get
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t fragment_id,
- GNUNET_PSYCSTORE_FragmentCallback cb,
- void *cb_cls) {
+static int
+fragment_get (void *cls,
+ const struct
+ GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t fragment_id,
+ GNUNET_PSYCSTORE_FragmentCallback cb,
+ void *cb_cls)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->select_fragment;
+ int ret = GNUNET_SYSERR;
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key),
+ SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 2, fragment_id))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_fragment (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = fragment_row (stmt, cb, cb_cls);
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_fragment (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_fragment (reset)");
+ }
+
+ return ret;
}
/**
@@ -675,14 +977,57 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_message_get
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t message_id,
- GNUNET_PSYCSTORE_FragmentCallback cb,
- void *cb_cls) {
+static int
+message_get (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t message_id,
+ GNUNET_PSYCSTORE_FragmentCallback cb,
+ void *cb_cls)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->select_message;
+ int ret = GNUNET_SYSERR;
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key),
+ SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_message (bind)");
+ }
+ else
+ {
+ int sql_ret;
+ do
+ {
+ sql_ret = sqlite3_step (stmt);
+ switch (sql_ret)
+ {
+ case SQLITE_DONE:
+ if (ret != GNUNET_OK)
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = fragment_row (stmt, cb, cb_cls);
+ if (ret != GNUNET_YES)
+ sql_ret = SQLITE_DONE;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_message (step)");
+ }
+ }
+ while (sql_ret == SQLITE_ROW);
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_message (reset)");
+ }
+
+ return ret;
}
/**
@@ -693,16 +1038,51 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_message_get_fragment
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t message_id,
- uint64_t fragment_offset,
- GNUNET_PSYCSTORE_FragmentCallback cb,
- void *cb_cls)
+static int
+message_get_fragment (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t message_id,
+ uint64_t fragment_offset,
+ GNUNET_PSYCSTORE_FragmentCallback cb,
+ void *cb_cls)
{
+ struct Plugin *plugin = cls;
+ int ret = GNUNET_SYSERR;
+ sqlite3_stmt *stmt = plugin->select_message_fragment;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key),
+ SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 3, fragment_offset))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_message_fragment (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = fragment_row (stmt, cb, cb_cls);
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_message_fragment (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_message_fragment (reset)");
+ }
+
+ return ret;
}
/**
@@ -712,15 +1092,50 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_counters_get_master
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t *fragment_id,
- uint64_t *message_id,
- uint64_t *group_generation)
+static int
+counters_get_master (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t *fragment_id,
+ uint64_t *message_id,
+ uint64_t *group_generation)
{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->select_counters_master;
+ int ret = GNUNET_SYSERR;
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key),
+ SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_counters_master (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ *fragment_id = sqlite3_column_int64 (stmt, 0);
+ *message_id = sqlite3_column_int64 (stmt, 1);
+ *group_generation = sqlite3_column_int64 (stmt, 2);
+ ret = GNUNET_OK;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_counters_master (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_counters_master (reset)");
+ }
+
+ return ret;
}
/**
@@ -730,12 +1145,48 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_counters_get_slave
- (void *cls,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- uint64_t *max_state_msg_id) {
+static int
+counters_get_slave (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ uint64_t *max_state_msg_id)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->select_counters_slave;
+ int ret = GNUNET_SYSERR;
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key),
+ SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_int64 (stmt, 2,
+ GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_counters_slave (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ *max_state_msg_id = sqlite3_column_int64 (stmt, 0);
+ ret = GNUNET_OK;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_counters_slave (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_counters_slave (reset)");
+ }
+
+ return ret;
}
/**
@@ -745,35 +1196,174 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_state_set
- (struct GNUNET_PSYCSTORE_Handle *h,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- const char *name,
- size_t value_size,
- const void *value) {
+static int
+state_set (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const char *name, const void *value, size_t value_size)
+{
+ struct Plugin *plugin = cls;
+ int ret = GNUNET_SYSERR;
+ sqlite3_stmt *stmt = plugin->insert_state_current;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_blob (stmt, 3, value, value_size,
+ SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_state_current (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_state_current (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "insert_state_current (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return ret;
}
+
/**
+ * Reset the state of a channel.
+ *
+ * @see GNUNET_PSYCSTORE_state_reset()
+ *
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+static int
+state_reset (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->delete_state;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "delete_state (bind)");
+ }
+ else if (SQLITE_DONE != sqlite3_step (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "delete_state (step)");
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "delete_state (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
+}
+
+
+/**
+ * Update signed values of state variables in the state store.
+ *
+ * @see GNUNET_PSYCSTORE_state_hash_update()
+ *
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+static int
+state_update_signed (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key)
+{
+ struct Plugin *plugin = cls;
+ sqlite3_stmt *stmt = plugin->update_state_signed;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "update_state_signed (bind)");
+ }
+ else if (SQLITE_DONE != sqlite3_step (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "update_state_signed (step)");
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "update_state_signed (reset)");
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
+}
+
+
+/**
* Retrieve a state variable by name.
*
- * @param name Name of the variable to retrieve.
- * @param[out] value_size Size of value.
- * @param[out] value Returned value.
+ * @see GNUNET_PSYCSTORE_state_get()
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_state_get
- (struct GNUNET_PSYCSTORE_Handle *h,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- const char *name,
- GNUNET_PSYCSTORE_StateCallback cb,
- void *cb_cls) {
+static int
+state_get (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const char *name, GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls)
+{
+ struct Plugin *plugin = cls;
+ int ret = GNUNET_SYSERR;
+ sqlite3_stmt *stmt = plugin->select_state_one;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key),
+ SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_one (bind)");
+ }
+ else
+ {
+ switch (sqlite3_step (stmt))
+ {
+ case SQLITE_DONE:
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = cb (cb_cls, name, sqlite3_column_blob (stmt, 0),
+ sqlite3_column_bytes (stmt, 0));
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_one (step)");
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_one (reset)");
+ }
+
+
+ return ret;
}
+
/**
* Retrieve all state variables for a channel with the given prefix.
*
@@ -781,21 +1371,130 @@
*
* @return #GNUNET_OK on success, else #GNUNET_SYSERR
*/
-int
-libgnunet_plugin_psycstore_sqlite_state_get_all
- (struct GNUNET_PSYCSTORE_Handle *h,
- const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
- const char *name,
- GNUNET_PSYCSTORE_StateCallback cb,
- void *cb_cls) {
+static int
+state_get_all (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const char *name, GNUNET_PSYCSTORE_StateCallback cb,
+ void *cb_cls)
+{
+ struct Plugin *plugin = cls;
+ int ret = GNUNET_SYSERR;
+ sqlite3_stmt *stmt = plugin->select_state_prefix;
+ size_t name_len = strlen (name);
+ char *name_prefix = GNUNET_malloc (name_len + 2);
+ memcpy (name_prefix, name, name_len);
+ memcpy (name_prefix + name_len, "_%", 2);
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC) ||
+ SQLITE_OK != sqlite3_bind_text (stmt, 2, name, name_len, SQLITE_STATIC)
||
+ SQLITE_OK != sqlite3_bind_text (stmt, 3, name_prefix, name_len + 2,
+ SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_prefix (bind)");
+ }
+ else
+ {
+ int sql_ret;
+ do
+ {
+ sql_ret = sqlite3_step (stmt);
+ switch (sql_ret)
+ {
+ case SQLITE_DONE:
+ if (ret != GNUNET_OK)
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0),
+ sqlite3_column_blob (stmt, 1),
+ sqlite3_column_bytes (stmt, 1));
+ if (ret != GNUNET_YES)
+ sql_ret = SQLITE_DONE;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_prefix (step)");
+ }
+ }
+ while (sql_ret == SQLITE_ROW);
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_prefix (reset)");
+ }
+
+ return ret;
}
-/**
+/**
+ * Retrieve all signed state variables for a channel.
+ *
+ * @see GNUNET_PSYCSTORE_state_get_signed()
+ *
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+static int
+state_get_signed (void *cls,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls)
+{
+ struct Plugin *plugin = cls;
+ int ret = GNUNET_SYSERR;
+
+ sqlite3_stmt *stmt = plugin->select_state_signed;
+
+ if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+ sizeof (*channel_key), SQLITE_STATIC))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_signed (bind)");
+ }
+ else
+ {
+ int sql_ret;
+ do
+ {
+ sql_ret = sqlite3_step (stmt);
+ switch (sql_ret)
+ {
+ case SQLITE_DONE:
+ if (ret != GNUNET_OK)
+ ret = GNUNET_NO;
+ break;
+ case SQLITE_ROW:
+ ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0),
+ sqlite3_column_blob (stmt, 1),
+ sqlite3_column_bytes (stmt, 1));
+ if (ret != GNUNET_YES)
+ sql_ret = SQLITE_DONE;
+ break;
+ default:
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_signed (step)");
+ }
+ }
+ while (sql_ret == SQLITE_ROW);
+ }
+
+ if (SQLITE_OK != sqlite3_reset (stmt))
+ {
+ LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+ "select_state_signed (reset)");
+ }
+
+ return ret;
+}
+
+
+/**
* Entry point for the plugin.
*
- * @param cls the "struct GNUNET_PSYCSTORE_PluginEnvironment*"
+ * @param cls The struct GNUNET_CONFIGURATION_Handle.
* @return NULL on error, otherwise the plugin context
*/
void *
@@ -816,21 +1515,23 @@
}
api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions);
api->cls = &plugin;
- api->membership_store = &libgnunet_plugin_psycstore_sqlite_membership_store;
- api->membership_test = &libgnunet_plugin_psycstore_sqlite_membership_test;
- api->fragment_store = &libgnunet_plugin_psycstore_sqlite_fragment_store;
- api->fragment_add_flags =
&libgnunet_plugin_psycstore_sqlite_fragment_add_flags;
- api->fragment_get = &libgnunet_plugin_psycstore_sqlite_fragment_get;
- api->message_get = &libgnunet_plugin_psycstore_sqlite_message_get;
- api->message_get_fragment =
&libgnunet_plugin_psycstore_sqlite_message_get_fragment;
- api->counters_get_master =
&libgnunet_plugin_psycstore_sqlite_counters_get_master;
- api->counters_get_slave =
&libgnunet_plugin_psycstore_sqlite_counters_get_slave;
- api->state_set = &libgnunet_plugin_psycstore_sqlite_state_set;
- api->state_get = &libgnunet_plugin_psycstore_sqlite_state_get;
- api->state_get_all = &libgnunet_plugin_psycstore_sqlite_state_get_all;
+ api->membership_store = &membership_store;
+ api->membership_test = &membership_test;
+ api->fragment_store = &fragment_store;
+ api->message_add_flags = &message_add_flags;
+ api->fragment_get = &fragment_get;
+ api->message_get = &message_get;
+ api->message_get_fragment = &message_get_fragment;
+ api->counters_get_master = &counters_get_master;
+ api->counters_get_slave = &counters_get_slave;
+ api->state_set = &state_set;
+ api->state_reset = &state_reset;
+ api->state_update_signed = &state_update_signed;
+ api->state_get = &state_get;
+ api->state_get_all = &state_get_all;
+ api->state_get_signed = &state_get_signed;
- LOG (GNUNET_ERROR_TYPE_INFO,
- _("Sqlite database running\n"));
+ LOG (GNUNET_ERROR_TYPE_INFO, _("SQLite database running\n"));
return api;
}
@@ -838,8 +1539,8 @@
/**
* Exit point from the plugin.
*
- * @param cls the plugin context (as returned by "init")
- * @return always NULL
+ * @param cls The plugin context (as returned by "init")
+ * @return Always NULL
*/
void *
libgnunet_plugin_psycstore_sqlite_done (void *cls)
@@ -850,8 +1551,7 @@
database_shutdown (plugin);
plugin->cfg = NULL;
GNUNET_free (api);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "sqlite plugin is finished\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "SQLite plugin is finished\n");
return NULL;
}
Modified: gnunet/src/psycstore/psycstore.conf
===================================================================
--- gnunet/src/psycstore/psycstore.conf 2013-09-03 19:16:43 UTC (rev 28973)
+++ gnunet/src/psycstore/psycstore.conf 2013-09-03 22:33:21 UTC (rev 28974)
@@ -2,7 +2,7 @@
AUTOSTART = YES
HOME = $SERVICEHOME
BINARY = gnunet-service-psycstore
-UNIXPATH = /tmp/gnunet-service-psycstore.unix
+UNIXPATH = /tmp/gnunet-service-psycstore.sock
UNIX_MATCH_UID = NO
UNIX_MATCH_GID = YES
DATABASE = sqlite
Modified: gnunet/src/psycstore/psycstore.h
===================================================================
--- gnunet/src/psycstore/psycstore.h 2013-09-03 19:16:43 UTC (rev 28973)
+++ gnunet/src/psycstore/psycstore.h 2013-09-03 22:33:21 UTC (rev 28974)
@@ -35,7 +35,7 @@
/**
* Answer from service to client about last operation.
*/
-struct GNUNET_PSYCSTORE_ResultCodeMessage
+struct ResultCodeMessage
{
/**
* Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE
@@ -52,6 +52,32 @@
};
+
+/**
+ * @see GNUNET_PSYCSTORE_membership_store()
+ */
+struct MembershipStoreMessage
+{
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key;
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key;
+ int did_join;
+ uint64_t announced_at;
+ uint64_t effective_since;
+ uint64_t group_generation;
+};
+
+
+/**
+ * @see GNUNET_PSYCSTORE_membership_test()
+ */
+struct MembershipTestMessage
+{
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key;
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key;
+ uint64_t message_id;
+ uint64_t group_generation;
+};
+
GNUNET_NETWORK_STRUCT_END
#endif
Modified: gnunet/src/psycstore/psycstore_api.c
===================================================================
--- gnunet/src/psycstore/psycstore_api.c 2013-09-03 19:16:43 UTC (rev
28973)
+++ gnunet/src/psycstore/psycstore_api.c 2013-09-03 22:33:21 UTC (rev
28974)
@@ -187,7 +187,7 @@
{
struct GNUNET_PSYCSTORE_Handle *h = cls;
struct GNUNET_PSYCSTORE_OperationHandle *op;
- const struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm;
+ const struct ResultCodeMessage *rcm;
const char *str;
uint16_t size;
@@ -203,22 +203,22 @@
switch (ntohs (msg->type))
{
case GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE:
- if (size < sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage))
+ if (size < sizeof (struct ResultCodeMessage))
{
GNUNET_break (0);
reschedule_connect (h);
return;
}
- rcm = (const struct GNUNET_PSYCSTORE_ResultCodeMessage *) msg;
+ rcm = (const struct ResultCodeMessage *) msg;
str = (const char *) &rcm[1];
- if ( (size > sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) &&
- ('\0' != str[size - sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)
- 1]) )
+ if ( (size > sizeof (struct ResultCodeMessage)) &&
+ ('\0' != str[size - sizeof (struct ResultCodeMessage) - 1]) )
{
GNUNET_break (0);
reschedule_connect (h);
return;
}
- if (size == sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage))
+ if (size == sizeof (struct ResultCodeMessage))
str = NULL;
op = h->op_head;
@@ -341,7 +341,6 @@
h->client = GNUNET_CLIENT_connect ("psycstore", h->cfg);
GNUNET_assert (NULL != h->client);
transmit_next (h);
- GNUNET_assert (NULL != h->th);
}
@@ -399,7 +398,7 @@
* was already transmitted, the service may still choose to complete
* the operation.
*
- * @param op operation to cancel
+ * @param op Operation to cancel.
*/
void
GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op)
@@ -435,4 +434,33 @@
}
+struct GNUNET_PSYCSTORE_OperationHandle *
+GNUNET_PSYCSTORE_membership_store (
+ struct GNUNET_PSYCSTORE_Handle *h,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+ int did_join,
+ uint64_t announced_at,
+ uint64_t effective_since,
+ uint64_t group_generation,
+ GNUNET_PSYCSTORE_ResultCallback rcb,
+ void *rcb_cls)
+{
+
+}
+
+
+struct GNUNET_PSYCSTORE_OperationHandle *
+GNUNET_PSYCSTORE_membership_test (
+ struct GNUNET_PSYCSTORE_Handle *h,
+ const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+ const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+ uint64_t message_id,
+ uint64_t group_generation,
+ GNUNET_PSYCSTORE_ResultCallback rcb,
+ void *rcb_cls)
+{
+
+}
+
/* end of psycstore_api.c */
Added: gnunet/src/psycstore/test_plugin_psycstore.c
===================================================================
--- gnunet/src/psycstore/test_plugin_psycstore.c
(rev 0)
+++ gnunet/src/psycstore/test_plugin_psycstore.c 2013-09-03 22:33:21 UTC
(rev 28974)
@@ -0,0 +1,375 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+/*
+ * @file psycstore/test_plugin_psycstore.c
+ * @brief Test for the psycstore plugins
+ * @author Gabor X Toth
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_lib.h"
+#include "gnunet_psycstore_plugin.h"
+#include "gnunet_psycstore_service.h"
+#include "gnunet_multicast_service.h"
+
+#define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING
+#if DEBUG_PSYCSTORE
+# define LOG_LEVEL "DEBUG"
+#else
+# define LOG_LEVEL "WARNING"
+#endif
+
+#define C2ARG(str) str, (sizeof (str) - 1)
+
+#define LOG(kind,...) GNUNET_log_from (kind, "test-plugin-psycstore",
__VA_ARGS__)
+
+#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__,
__LINE__); goto FAILURE;} } while (0)
+
+static int ok;
+
+/**
+ * Name of plugin under test.
+ */
+static const char *plugin_name;
+
+static struct GNUNET_CRYPTO_EccPrivateKey *channel_key;
+static struct GNUNET_CRYPTO_EccPrivateKey *slave_key;
+
+static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key;
+static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key;
+
+/**
+ * Function called when the service shuts down. Unloads our psycstore
+ * plugin.
+ *
+ * @param api api to unload
+ */
+static void
+unload_plugin (struct GNUNET_PSYCSTORE_PluginFunctions *api)
+{
+ char *libname;
+
+ GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
+ GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api));
+ GNUNET_free (libname);
+}
+
+
+/**
+ * Load the psycstore plugin.
+ *
+ * @param cfg configuration to pass
+ * @return NULL on error
+ */
+static struct GNUNET_PSYCSTORE_PluginFunctions *
+load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_PSYCSTORE_PluginFunctions *ret;
+ char *libname;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' psycstore plugin\n"),
+ plugin_name);
+ GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
+ if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg)))
+ {
+ FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name);
+ return NULL;
+ }
+ GNUNET_free (libname);
+ return ret;
+}
+
+
+struct FragmentClosure
+{
+ uint8_t n;
+ uint64_t flags[16];
+ struct GNUNET_MULTICAST_MessageHeader *msg[16];
+};
+
+static int
+fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2,
+ enum GNUNET_PSYCSTORE_MessageFlags flags)
+{
+ struct FragmentClosure *fcls = cls;
+ struct GNUNET_MULTICAST_MessageHeader *msg1 = fcls->msg[fcls->n];
+ uint64_t flags1 = fcls->flags[fcls->n++];
+ int ret;
+
+ if (flags1 == flags && msg1->header.size == msg2->header.size
+ && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n",
+ msg1->fragment_id);
+ ret = GNUNET_YES;
+ }
+ else
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n",
+ msg1->fragment_id);
+ ret = GNUNET_SYSERR;
+ }
+
+ GNUNET_free (msg2);
+ return ret;
+}
+
+
+struct StateClosure {
+ size_t n;
+ void *value[16];
+ size_t value_size[16];
+};
+
+static int
+state_cb (void *cls, const char *name, const void *value, size_t value_size)
+{
+ struct StateClosure *scls = cls;
+ const void *val = scls->value[scls->n];
+ size_t val_size = scls->value_size[scls->n++];
+
+ return value_size == val_size && 0 == memcmp (value, val, val_size)
+ ? GNUNET_YES
+ : GNUNET_SYSERR;
+}
+
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_PSYCSTORE_PluginFunctions *db;
+
+ ok = 1;
+ db = load_plugin (cfg);
+ if (NULL == db)
+ {
+ FPRINTF (stderr,
+ "%s",
+ "Failed to initialize PSYCstore. "
+ "Database likely not setup, skipping test.\n");
+ return;
+ }
+
+ /* Membership */
+
+ channel_key = GNUNET_CRYPTO_ecc_key_create ();
+ slave_key = GNUNET_CRYPTO_ecc_key_create ();
+
+ GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key);
+ GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key);
+
+ ASSERT (GNUNET_OK == db->membership_store(db->cls, &channel_pub_key,
+ &slave_pub_key, GNUNET_YES,
+ 4, 2, 1));
+
+ ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key,
+ &slave_pub_key, 4));
+
+ ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key,
+ &slave_pub_key, 2));
+
+ ASSERT (GNUNET_NO == db->membership_test(db->cls, &channel_pub_key,
+ &slave_pub_key, 1));
+
+
+ /* Messages */
+
+ struct GNUNET_MULTICAST_MessageHeader *msg
+ = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
+ ASSERT (msg != NULL);
+
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
+ msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key));
+
+ msg->hop_counter = 9;
+ msg->fragment_id = INT64_MAX - 1;
+ msg->fragment_offset = 0;
+ msg->message_id = INT64_MAX - 2;
+ msg->group_generation = INT64_MAX - 3;
+ msg->flags = GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT;
+
+ memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key));
+
+ msg->purpose.size = htonl (ntohs (msg->header.size)
+ - sizeof (msg->header)
+ - sizeof (msg->hop_counter)
+ - sizeof (msg->signature));
+ msg->purpose.purpose = htonl (234);
+ GNUNET_CRYPTO_ecc_sign (slave_key, &msg->purpose, &msg->signature);
+
+ struct FragmentClosure fcls = { 0 };
+ fcls.n = 0;
+ fcls.msg[0] = msg;
+ fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE;
+
+ ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg,
+ fcls.flags[0]));
+
+ ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
+ msg->fragment_id,
+ fragment_cb, &fcls));
+ ASSERT (fcls.n == 1);
+
+ fcls.n = 0;
+
+ ASSERT (GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key,
+ msg->message_id,
+ msg->fragment_offset,
+ fragment_cb, &fcls));
+ ASSERT (fcls.n == 1);
+
+ ASSERT (GNUNET_OK == db->message_add_flags (
+ db->cls, &channel_pub_key, msg->message_id,
+ GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED));
+
+ fcls.n = 0;
+ fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED;
+
+ ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
+ msg->fragment_id,
+ fragment_cb, &fcls));
+ ASSERT (fcls.n == 1);
+
+ struct GNUNET_MULTICAST_MessageHeader *msg1
+ = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key));
+
+ memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key));
+
+ msg1->fragment_id++;
+ msg1->fragment_offset += 32768;
+
+ fcls.n = 0;
+ fcls.msg[1] = msg1;
+ fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH;
+
+ ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1,
+ fcls.flags[1]));
+
+ ASSERT (GNUNET_OK == db->message_get (db->cls, &channel_pub_key,
+ msg->message_id,
+ fragment_cb, &fcls));
+ ASSERT (fcls.n == 2);
+
+ uint64_t max_state_msg_id = 0;
+ ASSERT (GNUNET_OK == db->counters_get_slave (db->cls, &channel_pub_key,
+ &max_state_msg_id)
+ && max_state_msg_id == msg->message_id);
+
+ uint64_t fragment_id = 0, message_id = 0, group_generation = 0;
+ ASSERT (GNUNET_OK == db->counters_get_master (db->cls, &channel_pub_key,
+ &fragment_id, &message_id,
+ &group_generation)
+ && fragment_id == msg1->fragment_id
+ && message_id == msg1->message_id
+ && group_generation == msg1->group_generation);
+
+
+ /* State */
+
+ ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo",
+ C2ARG("one two three")));
+
+ ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo_bar",
+ slave_key,
+ sizeof (*slave_key)));
+
+ struct StateClosure scls = { 0 };
+ scls.n = 0;
+ scls.value[0] = "one two three";
+ scls.value_size[0] = strlen ("one two three");
+
+ ASSERT (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo",
+ state_cb, &scls));
+ ASSERT (scls.n == 1);
+
+ scls.n = 0;
+ scls.value[1] = slave_key;
+ scls.value_size[1] = sizeof (*slave_key);
+
+ ASSERT (GNUNET_OK == db->state_get_all (db->cls, &channel_pub_key, "_foo",
+ state_cb, &scls));
+ ASSERT (scls.n == 2);
+
+ scls.n = 0;
+ ASSERT (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key,
+ state_cb, &scls));
+ ASSERT (scls.n == 0);
+
+ ASSERT (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key));
+
+ scls.n = 0;
+ ASSERT (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key,
+ state_cb, &scls));
+ ASSERT (scls.n == 2);
+
+ ok = 0;
+
+FAILURE:
+
+ if (NULL != channel_key)
+ {
+ GNUNET_free (channel_key);
+ channel_key = NULL;
+ }
+ if (NULL != slave_key)
+ {
+ GNUNET_free (slave_key);
+ slave_key = NULL;
+ }
+
+ unload_plugin (db);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ char cfg_name[128];
+ char *const xargv[] = {
+ "test-plugin-psycstore",
+ "-c", cfg_name,
+ "-L", LOG_LEVEL,
+ NULL
+ };
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
+ GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL);
+ plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
+ GNUNET_snprintf (cfg_name, sizeof (cfg_name),
"test_plugin_psycstore_%s.conf",
+ plugin_name);
+ GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv,
+ "test-plugin-psycstore", "nohelp", options, &run, NULL);
+
+ if (ok != 0)
+ FPRINTF (stderr, "Missed some testcases: %d\n", ok);
+
+#if ! DEBUG_PSYCSTORE
+ GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
+#endif
+
+ return ok;
+}
+
+/* end of test_plugin_psycstore.c */
Added: gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf
===================================================================
--- gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf
(rev 0)
+++ gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf 2013-09-03
22:33:21 UTC (rev 28974)
@@ -0,0 +1,2 @@
+[psycstore-sqlite]
+FILENAME = /tmp/gnunet-test-plugin-psycstore-sqlite/sqlite.db
Modified: gnunet/src/psycstore/test_psycstore.c
===================================================================
--- gnunet/src/psycstore/test_psycstore.c 2013-09-03 19:16:43 UTC (rev
28973)
+++ gnunet/src/psycstore/test_psycstore.c 2013-09-03 22:33:21 UTC (rev
28974)
@@ -48,14 +48,19 @@
/**
* Handle to PSYCstore operation.
*/
-static struct GNUNET_PSYCSTORE_Operation *op;
+static struct GNUNET_PSYCSTORE_OperationHandle *op;
/**
* Handle for task for timeout termination.
*/
static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
+static struct GNUNET_CRYPTO_EccPrivateKey *channel_key;
+static struct GNUNET_CRYPTO_EccPrivateKey *slave_key;
+static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key;
+static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key;
+
/**
* Clean up all resources used.
*/
@@ -72,6 +77,16 @@
GNUNET_PSYCSTORE_disconnect (h);
h = NULL;
}
+ if (NULL != channel_key)
+ {
+ GNUNET_free (channel_key);
+ channel_key = NULL;
+ }
+ if (NULL != slave_key)
+ {
+ GNUNET_free (slave_key);
+ slave_key = NULL;
+ }
GNUNET_SCHEDULER_shutdown ();
}
@@ -119,7 +134,12 @@
&end_normally, NULL);
}
+void
+membership_store_result (void *cls, int result, const char *err_msg)
+{
+}
+
/**
* Main function of the test, run from scheduler.
*
@@ -136,6 +156,17 @@
&endbadly, NULL);
h = GNUNET_PSYCSTORE_connect (cfg);
GNUNET_assert (NULL != h);
+
+ channel_key = GNUNET_CRYPTO_ecc_key_create ();
+ slave_key = GNUNET_CRYPTO_ecc_key_create ();
+
+ GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key);
+ GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key);
+
+ op = GNUNET_PSYCSTORE_membership_store (h, &channel_pub_key, &slave_pub_key,
+ GNUNET_YES, 2, 2, 1,
+ &membership_store_result, NULL);
+
end ();
}
Modified: gnunet/src/psycstore/test_psycstore.conf
===================================================================
--- gnunet/src/psycstore/test_psycstore.conf 2013-09-03 19:16:43 UTC (rev
28973)
+++ gnunet/src/psycstore/test_psycstore.conf 2013-09-03 22:33:21 UTC (rev
28974)
@@ -3,4 +3,13 @@
UNIXPATH = /tmp/test-psycstore-service-arm.sock
[psycstore]
-DBFILE = /tmp/test-psycstore-service.sqlite
+AUTOSTART = YES
+HOME = $SERVICEHOME
+BINARY = gnunet-service-psycstore
+UNIXPATH = /tmp/test-gnunet-service-psycstore.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
+DATABASE = sqlite
+
+[psycstore-sqlite]
+FILENAME = $SERVICEHOME/psycstore/sqlite_test.db
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r28974 - in gnunet/src: include psycstore,
gnunet <=