X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Finclude%2Fgnunet_psyc_service.h;h=91dcd0b07ad741ae42410ac5057eb8a349b5f2fb;hb=27c12911f4f2aba2d90099270d70de846e83854f;hp=d35c68f7e5c0cbbcf76e072a2ab038f1c438ddb8;hpb=3b1199eb8f4a3319a13d34878a956f16c66a5b19;p=oweals%2Fgnunet.git diff --git a/src/include/gnunet_psyc_service.h b/src/include/gnunet_psyc_service.h index d35c68f7e..91dcd0b07 100644 --- a/src/include/gnunet_psyc_service.h +++ b/src/include/gnunet_psyc_service.h @@ -18,7 +18,7 @@ Boston, MA 02111-1307, USA. */ -/** +/** * @file include/gnunet_psyc_service.h * @brief PSYC service; high-level access to the PSYC protocol * note that clients of this API are NOT expected to @@ -36,7 +36,7 @@ * 'places' and 'persons' are combined within the same * abstraction, that of a "channel". Channels are identified * and accessed in this API using a public/private key. - * Higher-level applications should use NAMES within GADS + * Higher-level applications should use NAMES within GNS * to obtain public keys, and the distinction between * 'places' and 'persons' can then be made with the help * of the naming system (and/or conventions). @@ -52,7 +52,7 @@ * @c \#define for the maximum size of a variable). * - PSYC defines standard variables, methods, etc. This * library deliberately abstracts over all of these; a - * higher-level API should combine the naming system (GADS) + * higher-level API should combine the naming system (GNS) * and standard methods (message, join, part, warn, * fail, error) and variables (action, color, time, * tag, etc.). However, this API does take over the @@ -86,16 +86,78 @@ extern "C" #endif #include "gnunet_util_lib.h" -#include "gnunet_psyc_lib.h" +#include "gnunet_env_lib.h" #include "gnunet_multicast_service.h" -/** +/** * Version number of GNUnet-PSYC API. */ #define GNUNET_PSYC_VERSION 0x00000000 +/** + * Policy flags for a channel. + */ +enum GNUNET_PSYC_ChannelFlags +{ + /** + * Admission must be confirmed by the master. + */ + GNUNET_PSYC_CHANNEL_ADMISSION_CONTROL = 1 << 0, + + /** + * Past messages are only available to slaves who were admitted at the time + * they were sent to the channel. + */ + GNUNET_PSYC_CHANNEL_RESTRICTED_HISTORY = 1 << 1, +}; + +/** + * PSYC channel policies. + */ +enum GNUNET_PSYC_Policy +{ + /** + * Anyone can join the channel, without announcing his presence; + * all messages are always public and can be distributed freely. + * Joins may be announced, but this is not required. + */ + GNUNET_PSYC_CHANNEL_ANONYMOUS = 0, + + /** + * The master must approve membership to the channel, messages must only be + * distributed to current channel slaves. This includes the channel + * state as well as transient messages. + */ + GNUNET_PSYC_CHANNEL_PRIVATE + = GNUNET_PSYC_CHANNEL_ADMISSION_CONTROL + | GNUNET_PSYC_CHANNEL_RESTRICTED_HISTORY, + +#if IDEAS_FOR_FUTURE + /** + * Anyone can freely join the channel (no approval required); + * however, messages must only be distributed to current channel + * slaves, so the master must still acknowledge that the slave + * joined before transient messages are delivered. As approval is + * guaranteed, the presistent channel state can be synchronized freely + * immediately, prior to master confirmation. + */ + GNUNET_PSYC_CHANNEL_OPEN + = GNUNET_PSYC_CHANNEL_RESTRICTED_HISTORY, + + /** + * The master must approve joins to the channel, but past messages can be + * freely distributed to slaves. + */ + GNUNET_PSYC_CHANNEL_CLOSED + = GNUNET_PSYC_CHANNEL_ADMISSION_CONTROL, +, +#endif + +}; + + enum GNUNET_PSYC_MessageFlags { /** @@ -108,7 +170,7 @@ enum GNUNET_PSYC_MessageFlags */ GNUNET_PSYC_MESSAGE_LAST_FRAGMENT = 1 << 1, - /** + /** * OR'ed flags if message is not fragmented. */ GNUNET_PSYC_MESSAGE_NOT_FRAGMENTED @@ -118,11 +180,101 @@ enum GNUNET_PSYC_MessageFlags /** * Historic message, retrieved from PSYCstore. */ - GNUNET_PSYC_MESSAGE_HISTORIC = 1 << 2 + GNUNET_PSYC_MESSAGE_HISTORIC = 1 << 30 +}; + + +/** + * M + */ +struct GNUNET_PSYC_MessageMethod +{ + /** + * Type: GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD + */ + struct GNUNET_MessageHeader header; + + uint32_t reserved GNUNET_PACKED; + + /** + * Number of modifiers in the message. + */ + uint32_t mod_count GNUNET_PACKED; + + /** + * OR'ed GNUNET_PSYC_MasterTransmitFlags + */ + uint32_t flags GNUNET_PACKED; + + /** + * Sending slave's public key. + * NULL if the message is from the master, or when transmitting a message. + */ + struct GNUNET_CRYPTO_EddsaPublicKey slave_key; + + /* Followed by NUL-terminated method name. */ +}; + + +struct GNUNET_PSYC_MessageModifier +{ + /** + * Type: GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER + */ + struct GNUNET_MessageHeader header; + + /** + * Size of value. + */ + uint32_t value_size GNUNET_PACKED; + + /** + * Size of name, including NUL terminator. + */ + uint16_t name_size GNUNET_PACKED; + + /** + * enum GNUNET_ENV_Operator + */ + uint8_t oper; + + /* Followed by NUL-terminated name, then the value. */ }; -/** +enum GNUNET_PSYC_DataStatus +{ + /** + * To be continued. + */ + GNUNET_PSYC_DATA_CONT = 0, + + /** + * Reached the end of message. + */ + GNUNET_PSYC_DATA_END = 1, + + /** + * Cancelled before the end. + */ + GNUNET_PSYC_DATA_CANCEL = 2 +}; + + +struct GNUNET_PSYC_MessageData +{ + /** + * Type: GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA + */ + struct GNUNET_MessageHeader header; + + /** + * enum GNUNET_PSYC_DataStatus + */ + uint8_t status; +}; + +/** * Handle that identifies a join request. * * Used to match calls to #GNUNET_PSYC_JoinCallback to the @@ -130,93 +282,66 @@ enum GNUNET_PSYC_MessageFlags */ struct GNUNET_PSYC_JoinHandle; -/** - * Handle that identifies a part request. - * - * Used to match calls to #GNUNET_PSYC_PartCallback to the - * corresponding calls to GNUNET_PSYC_part_ack(). - */ -struct GNUNET_PSYC_PartHandle; - -/** - * Method called from PSYC upon receiving a message indicating a call - * to a @e method. +/** + * Method called from PSYC upon receiving a message indicating a call to a + * @e method. * * @param cls Closure. - * @param sender Who transmitted the message (master, except for messages - * from one of the slaves to the master). - * @param message_id Unique message counter for this message; - * (unique only in combination with the given sender for - * this channel). - * @param method_name Original method name from PSYC (may be more - * specific than the registered method name due to try-and-slice matching). - * FIXME: no try-and-slice for methods defined here. - * @param header_length Number of modifiers in header. - * @param header Modifiers present in the message. FIXME: use environment instead? + * @param slave_key Who transmitted the message. + * - NULL for multicast messages from the master. + * - The sending slave's public key for unicast requests from one of the + * slaves to the master. + * @param message_id Unique message counter for this message. + * Unique only in combination with the given sender for this channel. + * @param method_name Method name from PSYC. + * @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 (*GNUNET_PSYC_Method)(void *cls, - const struct GNUNET_PeerIdentity *sender, - uint64_t message_id, - const char *method_name, - size_t header_length, - GNUNET_PSYC_Modifier *header, - uint64_t data_offset, - size_t data_size, - const void *data, - enum GNUNET_PSYC_MessageFlags flags); +typedef int +(*GNUNET_PSYC_Method) (void *cls, + const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, + uint64_t message_id, + const char *method_name, + size_t modifier_count, + const struct GNUNET_ENV_Modifier *modifiers, + uint64_t data_offset, + const void *data, + size_t data_size, + enum GNUNET_PSYC_MessageFlags flags); -/** +/** * Method called from PSYC upon receiving a join request. * * @param cls Closure. - * @param peer Peer requesting to join. + * @param slave requesting to join. * @param method_name Method name in the join request. - * @param header_length Number of modifiers in header. - * @param header Modifiers present in the message. - * @param data_size Number of bytes in @a data. + * @param variable_count Number of elements in the @a variables array. + * @param variables Transient variables for the join request. * @param data Data stream given to the method (might not be zero-terminated * if data is binary). - */ -typedef int (*GNUNET_PSYC_JoinCallback)(void *cls, - const struct GNUNET_PeerIdentity *peer, - const char *method_name, - size_t header_length, - GNUNET_PSYC_Modifier *header, - size_t data_size, - const void *data, - struct GNUNET_PSYC_JoinHandle *jh); - - -/** - * Method called from PSYC upon receiving a part request. - * - * @param cls Closure. - * @param peer Peer requesting to leave. - * @param method_name Method name in the part request. - * @param header_length Number of modifiers in header. - * @param header Modifiers present in the message. * @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 jh Join handle to use with GNUNET_PSYC_join_decision() */ -typedef int (*GNUNET_PSYC_PartCallback)(void *cls, - const struct GNUNET_PeerIdentity *peer, - const char *method_name, - size_t header_length, - GNUNET_PSYC_Modifier *header, - size_t data_size, - const void *data, - struct GNUNET_PSYC_PartHandle *ph); +typedef int +(*GNUNET_PSYC_JoinCallback) (void *cls, + const struct GNUNET_CRYPTO_EddsaPublicKey + *slave_key, + const char *method_name, + size_t variable_count, + const struct GNUNET_ENV_Modifier *variables, + const void *data, + size_t data_size, + struct GNUNET_PSYC_JoinHandle *jh); -/** +/** * Function to call with the decision made for a join request. * * Must be called once and only once in response to an invocation of the @@ -224,40 +349,52 @@ typedef int (*GNUNET_PSYC_PartCallback)(void *cls, * * @param jh Join request handle. * @param is_admitted #GNUNET_YES if joining is approved, - * #GNUNET_NO if it is disapproved + * #GNUNET_NO if it is disapproved. + * @param relay_count Number of relays given. + * @param relays Array of suggested peers that might be useful relays to use + * when joining the multicast group (essentially a list of peers that + * are already part of the multicast group and might thus be willing + * to help with routing). If empty, only this local peer (which must + * be the multicast origin) is a good candidate for building the + * multicast tree. Note that it is unnecessary to specify our own + * peer identity in this array. * @param method_name Method name for the message transmitted with the response. - * @param env Environment: transient variables for the message. - * @param data_size Size of @a data. + * @param env Environment containing transient variables for the message, + * or NULL. * @param data Data of the message. + * @param data_size Size of @a data. */ void GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, int is_admitted, + uint32_t relay_count, + 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); -/** - * Send a part acknowledgment. - * - * @param ph Part handle. +/** + * Handle for the master of a PSYC channel. */ -void -GNUNET_PSYC_part_ack (struct GNUNET_PSYC_PartHandle *ph); +struct GNUNET_PSYC_Master; -/** - * Handle for the master of a PSYC channel. +/** + * Function called after the channel master started. + * + * @param cls Closure. + * @param last_message_id Last message ID sent to the channel. */ -struct GNUNET_PSYC_Master; +typedef void +(*GNUNET_PSYC_MasterStartCallback) (void *cls, uint64_t max_message_id); -/** - * Create a PSYC channel master. +/** + * Start a PSYC master channel. * - * Will create a multicast group identified by the given ECC key. Messages + * Will start a multicast group identified by the given ECC key. Messages * received from group members will be given to the respective handler methods. * If a new member wants to join a group, the "join" method handler will be * invoked; the join handler must then generate a "join" message to approve the @@ -267,84 +404,117 @@ struct GNUNET_PSYC_Master; * inform PSYC about the meaning of the respective events. * * @param cfg Configuration to use (to connect to PSYC service). - * @param priv_key ECC key that will be used to sign messages for this - * PSYC session; public key is used to identify the - * PSYC channel; FIXME: we'll likely want to use - * NOT the p512 curve here, but a cheaper one in the future - * Note that end-users will usually not use the private key - * directly, but rather look it up in GADS for places - * managed by other users, or select a file with the private - * key(s) when setting up their own channels - * @param join_policy What is the membership policy of the group? - * Used to automate group management decisions. - * @param method_cb Function to invoke on messages received from members. + * @param channel_key ECC key that will be used to sign messages for this + * PSYC session. The public key is used to identify the PSYC channel. + * Note that end-users will usually not use the private key directly, but + * rather look it up in GNS for places managed by other users, or select + * a file with the private key(s) when setting up their own channels + * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper + * one in the future. + * @param policy Channel policy specifying join and history restrictions. + * Used to automate join decisions. + * @param method Function to invoke on messages received from slaves. * @param join_cb Function to invoke when a peer wants to join. - * @param part_cb Function to invoke when a peer wants to part. - * @param cls Closure for the callbacks. + * @param master_started_cb Function to invoke after the channel master started. + * @param cls Closure for @a method and @a join_cb. * @return Handle for the channel master, NULL on error. */ struct GNUNET_PSYC_Master * -GNUNET_PSYC_master_create (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_CRYPTO_EccPrivateKey *priv_key, - enum GNUNET_MULTICAST_JoinPolicy join_policy, - GNUNET_PSYC_Method method_cb, - GNUNET_PSYC_JoinCallback join_cb, - GNUNET_PSYC_PartCallback part_cb, - void *cls); +GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key, + enum GNUNET_PSYC_Policy policy, + GNUNET_PSYC_Method method, + GNUNET_PSYC_JoinCallback join_cb, + GNUNET_PSYC_MasterStartCallback master_started_cb, + void *cls); -/** +/** * Function called to provide data for a transmission via PSYC. * * Note that returning #GNUNET_OK or #GNUNET_SYSERR (but not #GNUNET_NO) * invalidates the respective transmission handle. * * @param cls Closure. - * @param message_id Set to the unique message ID that was generated for - * this message. - * @param data_size[in,out] 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) + * #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. If 0 is returned in @a data_size the transmission is paused, + * and can be resumed with GNUNET_PSYC_master_transmit_resume(). * #GNUNET_YES if this completes the transmission (all data supplied) */ -typedef int (*GNUNET_PSYC_MasterReadyNotify)(void *cls, - uint64_t message_id, - size_t *data_size, - void *data); +typedef int +(*GNUNET_PSYC_MasterTransmitNotify) (void *cls, + size_t *data_size, + void *data); + + +/** + * Flags for transmitting messages to a channel by the master. + */ +enum GNUNET_PSYC_MasterTransmitFlags +{ + GNUNET_PSYC_MASTER_TRANSMIT_NONE = 0, + /** + * Whether this message should reset the channel state, + * i.e. remove all previously stored state variables. + */ + GNUNET_PSYC_MASTER_TRANSMIT_RESET_STATE = 1 << 0, + + /** + * Whether we need to increment the group generation counter after + * transmitting this message. + */ + GNUNET_PSYC_MASTER_TRANSMIT_INC_GROUP_GEN = 1 << 1, + + /** + * Add PSYC header variable with the hash of the current channel state. + */ + GNUNET_PSYC_MASTER_TRANSMIT_ADD_STATE_HASH = 1 << 2 +}; -/** +/** * Handle for a pending PSYC transmission operation. */ struct GNUNET_PSYC_MasterTransmitHandle; -/** +/** * Send a message to call a method to all members in the PSYC channel. * * @param master Handle to the PSYC channel. - * @param increment_group_generation #GNUNET_YES if we need to increment - * the group generation counter after transmitting this message. * @param method_name Which method should be invoked. - * @param env Environment: state operations and transient variables for the message. + * @param env Environment containing state operations and transient variables + * for the message, or NULL. * @param notify Function to call to obtain the arguments. * @param notify_cls Closure for @a notify. + * @param flags Flags for the message being transmitted. * @return Transmission handle, NULL on error (i.e. more than one request queued). */ struct GNUNET_PSYC_MasterTransmitHandle * GNUNET_PSYC_master_transmit (struct GNUNET_PSYC_Master *master, - int increment_group_generation, const char *method_name, const struct GNUNET_ENV_Environment *env, - GNUNET_PSYC_MasterReadyNotify notify, - void *notify_cls); + GNUNET_PSYC_MasterTransmitNotify notify, + void *notify_cls, + enum GNUNET_PSYC_MasterTransmitFlags flags); -/** +/** + * Resume transmission to the channel. + * + * @param th Handle of the request that is being resumed. + */ +void +GNUNET_PSYC_master_transmit_resume (struct GNUNET_PSYC_MasterTransmitHandle *th); + + +/** * Abort transmission request to channel. * * @param th Handle of the request that is being aborted. @@ -353,52 +523,84 @@ void GNUNET_PSYC_master_transmit_cancel (struct GNUNET_PSYC_MasterTransmitHandle *th); -/** - * Destroy a PSYC channel master. +/** + * Stop a PSYC master channel. * - * @param master PSYC channel master to terminate. + * @param master PSYC channel master to stop. */ -tvoid -GNUNET_PSYC_master_destroy (struct GNUNET_PSYC_Master *master); +void +GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master); -/** +/** * Handle for a PSYC channel slave. */ struct GNUNET_PSYC_Slave; -/** +/** + * Function called after the slave joined. + * + * @param cls Closure. + * @param max_message_id Last message ID sent to the channel. + */ +typedef void +(*GNUNET_PSYC_SlaveJoinCallback) (void *cls, uint64_t max_message_id); + + +/** * Join a PSYC channel. * * The entity joining is always the local peer. The user must immediately use - * the GNUNET_PSYC_slave_to_master() functions to transmit a @e join_msg to the + * the GNUNET_PSYC_slave_transmit() functions to transmit a @e join_msg to the * channel; if the join request succeeds, the channel state (and @e recent * method calls) will be replayed to the joining member. There is no explicit * notification on failure (as the channel may simply take days to approve, * and disapproval is simply being ignored). * * @param cfg Configuration to use. - * @param pub_key ECC key that identifies the channel we wish to join. + * @param channel_key ECC public key that identifies the channel we wish to join. + * @param slave_key ECC private-public key pair that identifies the slave, and + * used by multicast to sign the join request and subsequent unicast + * requests sent to the master. * @param origin Peer identity of the origin. + * @param relay_count Number of peers in the @a relays array. + * @param relays Peer identities of members of the multicast group, which serve + * as relays and used to join the group at. * @param method Function to invoke on messages received from the channel, - * typically at least contains functions for @e join and @e part. - * @param method_cls Closure for @a method. + * typically at least contains functions for @e join and @e part. + * @param join_cb function invoked once we have joined with the current + * message ID of the channel + * @param slave_joined_cb Function to invoke when a peer wants to join. + * @param cls Closure for @a method_cb and @a slave_joined_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. * @return Handle for the slave, NULL on error. */ struct GNUNET_PSYC_Slave * GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_CRYPTO_EccPublicKey *pub_key, + const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key, + const struct GNUNET_CRYPTO_EddsaPrivateKey *slave_key, const struct GNUNET_PeerIdentity *origin, + uint32_t relay_count, + const struct GNUNET_PeerIdentity *relays, GNUNET_PSYC_Method method, - void *method_cls); + GNUNET_PSYC_JoinCallback join_cb, + GNUNET_PSYC_SlaveJoinCallback slave_joined_cb, + void *cls, + const char *method_name, + const struct GNUNET_ENV_Environment *env, + const void *data, + uint16_t data_size); -/** +/** * Part a PSYC channel. * * Will terminate the connection to the PSYC service. Polite clients should - * first explicitly send a @e part request (via GNUNET_PSYC_slave_to_master()). + * first explicitly send a part request (via GNUNET_PSYC_slave_transmit()). * * @param slave Slave handle. */ @@ -406,52 +608,74 @@ void GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slave); -/** - * Function called to provide data for a transmission to the channel - * master (aka the @e host of the channel). +/** + * Function called to provide data for a transmission to the channel master + * (a.k.a. the @e host of the channel). * * Note that returning #GNUNET_OK or #GNUNET_SYSERR (but not #GNUNET_NO) * invalidates the respective transmission handle. * * @param cls Closure. - * @param data_size[in,out] 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[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. * @return #GNUNET_SYSERR on error (fatal, aborts transmission). * #GNUNET_NO on success, if more data is to be transmitted later. * #GNUNET_YES if this completes the transmission (all data supplied). */ -typedef int (*GNUNET_PSYC_SlaveReadyNotify)(void *cls, - size_t *data_size, - char *data); +typedef int +(*GNUNET_PSYC_SlaveTransmitNotify) (void *cls, + size_t *data_size, + char *data); + + +/** + * Flags for transmitting messages to the channel master by a slave. + */ +enum GNUNET_PSYC_SlaveTransmitFlags +{ + GNUNET_PSYC_SLAVE_TRANSMIT_NONE = 0 +}; -/** +/** * Handle for a pending PSYC transmission operation. */ struct GNUNET_PSYC_SlaveTransmitHandle; -/** +/** * Request a message to be sent to the channel master. * * @param slave Slave handle. * @param method_name Which (PSYC) method should be invoked (on host). - * @param env Environment: transient variables for the message. + * @param env Environment containing transient variables for the message, or NULL. * @param notify Function to call when we are allowed to transmit (to get data). * @param notify_cls Closure for @a notify. + * @param flags Flags for the message being transmitted. * @return Transmission handle, NULL on error (i.e. more than one request queued). */ struct GNUNET_PSYC_SlaveTransmitHandle * GNUNET_PSYC_slave_transmit (struct GNUNET_PSYC_Slave *slave, const char *method_name, const struct GNUNET_ENV_Environment *env, - GNUNET_PSYC_SlaveReadyNotify notify, - void *notify_cls); + GNUNET_PSYC_SlaveTransmitNotify notify, + void *notify_cls, + enum GNUNET_PSYC_SlaveTransmitFlags flags); + +/** + * Resume transmission to the master. + * + * @param th Handle of the request that is being resumed. + */ +void +GNUNET_PSYC_slave_transmit_resume (struct GNUNET_PSYC_MasterTransmitHandle *th); -/** + +/** * Abort transmission request to master. * * @param th Handle of the request that is being aborted. @@ -460,14 +684,15 @@ void GNUNET_PSYC_slave_transmit_cancel (struct GNUNET_PSYC_SlaveTransmitHandle *th); -/** +/** * Handle to access PSYC channel operations for both the master and slaves. */ struct GNUNET_PSYC_Channel; -/** - * Convert a channel @a master to a @e channel handle to access the @e channel APIs. +/** + * Convert a channel @a master to a @e channel handle to access the @e channel + * APIs. * * @param master Channel master handle. * @return Channel handle, valid for as long as @a master is valid. @@ -476,7 +701,7 @@ struct GNUNET_PSYC_Channel * GNUNET_PSYC_master_get_channel (struct GNUNET_PSYC_Master *master); -/** +/** * Convert @a slave to a @e channel handle to access the @e channel APIs. * * @param slave Slave handle. @@ -486,11 +711,11 @@ struct GNUNET_PSYC_Channel * GNUNET_PSYC_slave_get_channel (struct GNUNET_PSYC_Slave *slave); -/** - * Add a member to the channel. +/** + * Add a slave to the channel's membership list. * * Note that this will NOT generate any PSYC traffic, it will merely update the - * local data base to modify how we react to membership test queries. + * local database to modify how we react to membership test queries. * The channel master still needs to explicitly transmit a @e join message to * notify other channel members and they then also must still call this function * in their respective methods handling the @e join message. This way, how @e @@ -498,25 +723,27 @@ GNUNET_PSYC_slave_get_channel (struct GNUNET_PSYC_Slave *slave); * application; for example, there might be a @e part_all method to kick out * everyone. * - * Note that channel members are explicitly trusted to execute such methods - * correctly; not doing so correctly will result in either denying members + * Note that channel slaves are explicitly trusted to execute such methods + * correctly; not doing so correctly will result in either denying other slaves * access or offering access to channel data to non-members. * * @param channel Channel handle. - * @param member Which peer to add. - * @param message_id Message ID for the message that changed the membership. + * @param slave_key Identity of channel slave to add. + * @param announced_at ID of the message that announced the membership change. + * @param effective_since Addition of slave is in effect since this message ID. */ void -GNUNET_PSYC_channel_member_add (struct GNUNET_PSYC_Channel *channel, - const struct GNUNET_PeerIdentity *member, - uint64_t message_id); +GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *channel, + const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, + uint64_t announced_at, + uint64_t effective_since); -/** - * Remove a member from the channel. +/** + * Remove a slave from the channel's membership list. * * Note that this will NOT generate any PSYC traffic, it will merely update the - * local data base to modify how we react to membership test queries. + * local database to modify how we react to membership test queries. * The channel master still needs to explicitly transmit a @e part message to * notify other channel members and they then also must still call this function * in their respective methods handling the @e part message. This way, how @@ -530,36 +757,48 @@ GNUNET_PSYC_channel_member_add (struct GNUNET_PSYC_Channel *channel, * non-members. * * @param channel Channel handle. - * @param member Which peer to remove. - * @param message_id Message ID for the message that changed the membership. + * @param slave_key Identity of channel slave to remove. + * @param announced_at ID of the message that announced the membership change. */ void -GNUNET_PSYC_channel_member_remove (struct GNUNET_PSYC_Channel *channel, - const struct GNUNET_PeerIdentity *member, - uint64_t message_id); +GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel, + const struct GNUNET_CRYPTO_EddsaPublicKey + *slave_key, + uint64_t announced_at); -/** +/** * Function called to inform a member about stored state values for a channel. * * @param cls Closure. - * @param name Name of the state variable. + * @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. */ -typedef void (*GNUNET_PSYC_StateCallback)(void *cls, - const char *name, - size_t value_size, - const void *value); +typedef void +(*GNUNET_PSYC_StateCallback) (void *cls, + const char *name, + const void *value, + size_t value_size); + + +/** + * Function called when a requested operation has finished. + * + * @param cls Closure. + */ +typedef void +(*GNUNET_PSYC_FinishCallback) (void *cls); -/** +/** * Handle to a story telling operation. */ struct GNUNET_PSYC_Story; -/** +/** * Request to be told the message history of the channel. * * Historic messages (but NOT the state at the time) will be replayed (given to @@ -571,14 +810,13 @@ struct GNUNET_PSYC_Story; * @param start_message_id Earliest interesting point in history. * @param end_message_id Last (exclusive) interesting point in history. * @param method Function to invoke on messages received from the story. - * @param method_cls Closure for @a method. * @param finish_cb Function to call when the requested story has been fully * told (counting message IDs might not suffice, as some messages * might be secret and thus the listener would not know the story is * finished without being told explicitly); once this function * has been called, the client must not call * GNUNET_PSYC_channel_story_tell_cancel() anymore. - * @param finish_cb_cls Closure to finish_cb. + * @param cls Closure for the callbacks. * @return Handle to cancel story telling operation. */ struct GNUNET_PSYC_Story * @@ -586,12 +824,11 @@ GNUNET_PSYC_channel_story_tell (struct GNUNET_PSYC_Channel *channel, uint64_t start_message_id, uint64_t end_message_id, GNUNET_PSYC_Method method, - void *method_cls, - void (*finish_cb)(void *), - void *finish_cb_cls); + GNUNET_PSYC_FinishCallback *finish_cb, + void *cls); -/** +/** * Abort story telling. * * This function must not be called from within method handlers (as given to @@ -603,56 +840,64 @@ void GNUNET_PSYC_channel_story_tell_cancel (struct GNUNET_PSYC_Story *story); -/** - * Call the given callback on all matching values (including variables) in the - * channel state. - * - * The callback is invoked synchronously on all matching states (as the state is - * fully replicated in the library in this process; channel states should be - * small, large data is to be passed as streaming data to methods). +/** + * Handle for a state query operation. + */ +struct GNUNET_PSYC_StateQuery; + + +/** + * Retrieve the best matching channel state variable. * - * A name matches if it includes the @a state_name prefix, thus requesting the - * empty state ("") will match all values; requesting "_a_b" will also return - * values stored under "_a_b_c". + * If the requested variable name is not present in the state, the nearest + * less-specific name is matched; for example, requesting "_a_b" will match "_a" + * if "_a_b" does not exist. * * @param channel Channel handle. - * @param state_name Name of the state to query (full name - * might be longer, this is only the prefix that must match). - * @param cb Function to call on the matching state values. - * @param cb_cls Closure for @a cb. - * @return Message ID for which the state was returned (last seen - * message ID). - */ -uint64_t -GNUNET_PSYC_channel_state_get_all (struct GNUNET_PSYC_Channel *channel, - const char *state_name, - GNUNET_PSYC_StateCallback cb, - void *cb_cls); + * @param full_name Full name of the requested variable, the actual variable + * returned might have a shorter name.. + * @param cb Function called once when a matching state variable is found. + * Not called if there's no matching state variable. + * @param cb_cls Closure for the callbacks. + * @return Handle that can be used to cancel the query operation. + */ +struct GNUNET_PSYC_StateQuery * +GNUNET_PSYC_channel_state_get (struct GNUNET_PSYC_Channel *channel, + const char *full_name, + GNUNET_PSYC_StateCallback cb, + void *cb_cls); -/** - * Obtain the current value of the best-matching value in the state - * (including variables). +/** + * Return all channel state variables whose name matches a given prefix. * - * Note that variables are only valid during a #GNUNET_PSYC_Method invocation, as - * variables are only valid for the duration of a method invocation. + * A name matches if it starts with the given @a name_prefix, thus requesting + * the empty prefix ("") will match all values; requesting "_a_b" will also + * return values stored under "_a_b_c". * - * If the requested variable name does not have an exact state in - * the state, the nearest less-specific name is matched; for example, - * requesting "_a_b" will match "_a" if "_a_b" does not exist. + * The @a state_cb is invoked on all matching state variables asynchronously, as + * the state is stored in and retrieved from the PSYCstore, * * @param channel Channel handle. - * @param variable_name Name of the variable to query. - * @param[out] return_value_size Set to number of bytes in variable, - * needed as variables might contain binary data and - * might also not be 0-terminated; set to 0 on errors. - * @return NULL on error (no matching state or variable), pointer - to the respective value otherwise. - */ -const void * -GNUNET_PSYC_channel_state_get (struct GNUNET_PSYC_Channel *channel, - const char *variable_name, - size_t *return_value_size); + * @param name_prefix Prefix of the state variable name to match. + * @param cb Function to call with the matching state variables. + * @param cb_cls Closure for the callbacks. + * @return Handle that can be used to cancel the query operation. + */ +struct GNUNET_PSYC_StateQuery * +GNUNET_PSYC_channel_state_get_prefix (struct GNUNET_PSYC_Channel *channel, + const char *name_prefix, + GNUNET_PSYC_StateCallback cb, + void *cb_cls); + + +/** + * Cancel a state query operation. + * + * @param query Handle for the operation to cancel. + */ +void +GNUNET_PSYC_channel_state_get_cancel (struct GNUNET_PSYC_StateQuery *query); #if 0 /* keep Emacsens' auto-indent happy */