psyc apis
[oweals/gnunet.git] / src / include / gnunet_psyc_service.h
1 /*
2      This file is part of GNUnet.
3      (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file include/gnunet_psyc_service.h
23  * @brief PSYC service; high-level access to the PSYC protocol
24  *        note that clients of this API are NOT expected to
25  *        understand the PSYC message format, only the semantics!
26  *        Parsing (and serializing) the PSYC stream format is done
27  *        within the implementation of the libgnunetpsyc library,
28  *        and this API deliberately exposes as little as possible
29  *        of the actual data stream format to the application!
30  * @author Christian Grothoff
31  *
32  * NOTE:
33  * - this API does not know about psyc's "root" and "places";
34  *   there is no 'root' in GNUnet-Psyc as we're decentralized;
35  *   'places' and 'persons' are combined within the same 
36  *   abstraction, that of a "channel".  Channels are identified
37  *   and accessed in this API using a public/private key.  
38  *   Higher-level applications should use NAMES within GADS
39  *   to obtain public keys, and the distinction between 
40  *   'places' and 'persons' can then be made with the help
41  *   of the naming system (and/or conventions).
42  *   Channels are (as in PSYC) organized into a hierarchy; each
43  *   channel owner (the one with the private key) is then
44  *   the operator of the multicast group (its Origin in 
45  *   the terminology of the multicast API).
46  * - The API supports passing large amounts of data using
47  *   'streaming' for the argument passed to a method.  State
48  *   and variables must fit into memory and cannot be streamed
49  *   (thus, no passing of 4 GB of data in a variable; 
50  *   once we implement this, we might want to create a
51  *   #define for the maximum size of a variable).
52  * - PSYC defines standard variables, methods, etc.  This
53  *   library deliberately abstracts over all of these; a
54  *   higher-level API should combine the naming system (GADS)
55  *   and standard methods (message, join, leave, warn,
56  *   fail, error) and variables (action, color, time,
57  *   tag, etc.).  However, this API does take over the
58  *   routing variables, specifically 'context' (channel),
59  *   and 'source'.  We only kind-of support 'target', as
60  *   the target is either everyone in the group or the
61  *   origin, and never just a single member of the group;
62  *   for such individual messages, an application needs to
63  *   construct an 'inbox' channel where the owner (only)
64  *   receives messages (but never forwards; private responses
65  *   would be transmitted by joining the senders 'inbox'
66  *   channel -- or a inbox#bob subchannel).  The
67  *   goal for all of this is to keep the abstractions in this 
68  *   API minimal: interaction with multicast, try \& slice,
69  *   state/variable/channel management.  Higher-level
70  *   operations belong elsewhere (so maybe this API should
71  *   be called 'PSYC-low', whereas a higher-level API
72  *   implementing defaults for standard methods and
73  *   variables might be called 'PSYC-std' or 'PSYC-high'.
74  */
75
76 #ifndef GNUNET_PSYC_SERVICE_H
77 #define GNUNET_PSYC_SERVICE_H
78
79 #ifdef __cplusplus
80 extern "C"
81 {
82 #if 0                           /* keep Emacsens' auto-indent happy */
83 }
84 #endif
85 #endif
86
87 #include "gnunet_util_lib.h"
88 #include "gnunet_multicast_service.h"
89
90
91 /**
92  * Version number of GNUnet-PSYC API.
93  */
94 #define GNUNET_PSYC_VERSION 0x00000000
95
96
97 /**
98  * Information flags for data fragments set via PSYC.
99  */
100 enum GNUNET_PSYC_FragmentStatus
101 {
102   /**
103    * This is the first part of data for the given method call.
104    */
105   GNUNET_PSYC_FS_FIRST = 1,
106   
107   /**
108    * This is the last part of data for the given method call.
109    */
110   GNUNET_PSYC_FS_LAST = 2,
111
112   /**
113    * OR'ed flags if payload is not fragmented.
114    */
115   GNUNET_PSYC_FS_NOT_FRAGMENTED = (GNUNET_PSYC_FS_FIRST | GNUNET_PSYC_FS_LAST)
116 };
117
118
119 /**
120  * Method called from PSYC upon receiving a message indicating a call
121  * to a 'method'.  
122  *
123  * @param cls closure
124  * @param full_method_name original method name from PSYC (may be more
125  *        specific than the registered method name due to try-and-slice matching)
126  * @param sender who transmitted the message (origin, except for messages
127  *        from one of the members to the origin)
128  * @param message_id unique message counter for this message;
129  *                   (unique only in combination with the given sender for
130  *                    this channel)
131  * @param group_generation group generation counter for this message
132  *                   (always zero for messages from members to channel owner); FIXME: needed?
133  * @param data_off byte offset of 'data' in the overall data of the method
134  * @param data_size number of bytes in 'data'; 
135  * @param data data stream given to the method (might not be zero-terminated 
136  *             if data is binary)
137  * @param frag fragmentation status for the data
138  */
139 typedef int (*GNUNET_PSYC_Method)(void *cls,
140                                   const char *full_method_name,
141                                   const struct GNUNET_PeerIdentity *sender,
142                                   uint64_t message_id,
143                                   uint64_t group_generation,
144                                   uint64_t data_off,
145                                   size_t data_size,
146                                   const void *data,
147                                   enum GNUNET_PSYC_FragmentStatus frag);
148
149
150 /**
151  * Handle for the channel of a PSYC group.
152  */
153 struct GNUNET_PSYC_Channel;
154
155
156 /**
157  * Start a PSYC channel.  Will create a multicast group identified by
158  * the given ECC key.  Messages recevied from group members will be
159  * given to the respective handler methods.  If a new member wants to
160  * join a group, the "join" method handler will be invoked; the join
161  * handler must then generate a "join" message to approve the joining
162  * of the new member.  The channel can also change group membership
163  * without explicit requests.  Note that PSYC doesn't itself "understand"
164  * join or leave messages, the respective methods must call other
165  * PSYC functions to inform PSYC about the meaning of the respective
166  * events.
167  *
168  * @param cfg configuration to use (to connect to PSYC service)
169  * @param method functions to invoke on messages received from members,
170  *                typcially at least contains functions for 'join' and 'leave'.
171  * @param method_cls closure for 'method'
172  * @param priv_key ECC key that will be used to sign messages for this
173  *                 PSYC session; public key is used to identify the
174  *                 PSYC group; FIXME: we'll likely want to use
175  *                 NOT the p521 curve here, but a cheaper one in the future
176  *                 Note that end-users will usually not use the private key
177  *                 directly, but rather look it up in GADS for groups 
178  *                 managed by other users, or select a file with the private
179  *                 key(s) when setting up their own channels
180  * @param join_policy what is the membership policy of the group?
181  *                 Used to automate group management decisions.
182  * @return handle for the channel, NULL on error 
183  */
184 struct GNUNET_PSYC_Channel *
185 GNUNET_PSYC_channel_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 
186                            GNUNET_PSYC_Method method,
187                            void *method_cls,
188                            const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
189                            enum GNUNET_MULTICAST_JoinPolicy join_policy);
190
191
192 /**
193  * Possible operations on PSYC state (persistent) and variables (per message).
194  */
195 enum GNUNET_PSYC_Operator
196 {
197   /**
198    * Replace the full state with the new value ("=").
199    */
200   GNUNET_PSYC_SOT_SET_STATE = 0,
201   
202   /**
203    * Delete the complete entry from the state (given data must be
204    * empty).  Equivalent to 'SET' with emtpy data, but more
205    * explicit ("=");
206    */
207   GNUNET_PSYC_SOT_DELETE = 0,
208   
209   /**
210    * Set the value of a variable to a new value (":").
211    */
212   GNUNET_PSYC_SOT_SET_VARIABLE,
213   
214   /**
215    * Add the given value to the set of values in the state ("+").
216    */
217   GNUNET_PSYC_SOT_ADD_STATE,
218   
219   /**
220    * Remove the given value from the set of values in the state ("-").
221    */
222   GNUNET_PSYC_SOT_REMOVE_STATE
223   
224 };
225
226
227 /**
228  * Update channel state (or set a variable).  The state of a channel
229  * must fit into the memory of each member (and the channel); large
230  * values that require streaming must only be passed as the stream
231  * arguments to methods.  State updates might not be transmitted to
232  * group members until the next call to
233  * 'GNUNET_PSYC_channel_notify_transmit_ready'.  Variable updates must
234  * be given just before the call to the respective method that needs
235  * the variables.
236  *
237  * @param channel handle to the PSYC group / channel
238  * @param full_state_name name of the field in the channel state to change
239  * @param type kind of update operation (add, remove, replace, delete)
240  * @param data_size number of bytes in data
241  * @param data new state value
242  * @return GNUNET_OK on success, GNUNET_SYSERR on internal error
243  *        (i.e. state too large)
244  */
245 int
246 GNUNET_PSYC_channel_state_update (struct GNUNET_PSYC_Channel *channel,
247                                   const char *full_state_name,
248                                   enum GNUNET_PSYC_Operator type,
249                                   size_t data_size,
250                                   const void *data);
251
252
253 /**
254  * Function called to provide data for a transmission via PSYC.  Note
255  * that returning GNUNET_OK or GNUNET_SYSERR (but not GNUNET_NO)
256  * invalidates the respective transmission handle.
257  *
258  * @param cls closure
259  * @param message_id set to the unique message ID that was generated for
260  *        this message
261  * @param group_generation set to the group generation used for this
262  *        message
263  * @param data_size initially set to the number of bytes available in 'data',
264  *        should be set to the number of bytes written to data (IN/OUT)
265  * @param data where to write the body of the message to give to the method;
266  *        function must copy at most '*data_size' bytes to 'data'.
267  * @return GNUNET_SYSERR on error (fatal, aborts transmission)
268  *         GNUNET_NO on success, if more data is to be transmitted later 
269  *         (should be used if 'data_size' was not big enough to take all the data)
270  *         GNUNET_YES if this completes the transmission (all data supplied)
271  */
272 typedef int (*GNUNET_PSYC_ChannelReadyNotify)(void *cls,
273                                               uint64_t message_id,
274                                               uint64_t group_generation,
275                                               size_t *data_size,
276                                               void *data);
277
278
279 /**
280  * Handle for a pending PSYC transmission operation.
281  */
282 struct GNUNET_PSYC_ChannelTransmitHandle;
283
284
285 /**
286  * Send a message to call a method to all members in the PSYC channel.
287  *
288  * @param channel handle to the PSYC multicast group
289  * @param increment_group_generation GNUNET_YES if we need to increment
290  *        the group generation counter after transmitting this message
291  * @param full_method_name which method should be invoked
292  * @param notify function to call to obtain the arguments
293  * @param notify_cls closure for 'notify'
294  * @return transmission handle, NULL on error (i.e. more than one request queued)
295  */
296 struct GNUNET_PSYC_ChannelTransmitHandle *
297 GNUNET_PSYC_channel_notify_transmit_ready (struct GNUNET_PSYC_Channel *channel,
298                                            int increment_group_generation,
299                                            const char *full_method_name,
300                                            GNUNET_PSYC_ChannelReadyNotify notify,
301                                            void *notify_cls);
302
303
304 /**
305  * Abort transmission request to channel.
306  *
307  * @param th handle of the request that is being aborted
308  */
309 void
310 GNUNET_PSYC_channel_notify_transmit_ready_cancel (struct GNUNET_PSYC_ChannelTransmitHandle *th);
311
312
313 /**
314  * End a PSYC channel.
315  *
316  * @param channel PSYC channel to terminate
317  */
318 void
319 GNUNET_PSYC_channel_end (struct GNUNET_PSYC_Channel *channel);
320
321
322 /**
323  * Handle to access PSYC group operations for all members.
324  */
325 struct GNUNET_PSYC_Group;
326
327
328 /**
329  * Convert 'channel' to a 'group' handle to access the 'group' APIs.
330  * 
331  * @param channel channel handle
332  * @return group handle, valid for as long as 'channel' is valid
333  */ 
334 struct GNUNET_PSYC_Group *
335 GNUNET_PSYC_channel_get_group (struct GNUNET_PSYC_Channel *channel);
336
337
338 /**
339  * Convert 'member' to a 'group' handle to access the 'group' APIs.
340  * 
341  * @param member membership handle
342  * @return group handle, valid for as long as 'member' is valid
343  */ 
344 struct GNUNET_PSYC_Group *
345 GNUNET_PSYC_member_get_group (struct GNUNET_PSYC_Member *member);
346
347
348 /**
349  * Add a member to the group.    Note that this will NOT generate any
350  * PSYC traffic, it will merely update the local data base to modify
351  * how we react to 'membership test' queries.  The channel still needs to
352  * explicitly transmit a 'join' message to notify other group members
353  * and they then also must still call this function in their respective
354  * methods handling the 'join' message.  This way, how 'join' and 'leave'
355  * operations are exactly implemented is still up to the application;
356  * for example, there might be a 'leave_all' method to kick out everyone.
357  *
358  * Note that group members are explicitly trusted to execute such 
359  * methods correctly; not doing so correctly will result in either
360  * denying members access or offering access to group data to
361  * non-members.
362  *
363  * @param group group handle
364  * @param member which peer to add
365  * @param message_id message ID for the message that changed the membership
366  * @param group_generation the generation ID where the change went into effect
367  */
368 void
369 GNUNET_PSYC_group_member_add (struct GNUNET_PSYC_Group *group,
370                               const struct GNUNET_PeerIdentity *member,
371                               uint64_t message_id,
372                               uint64_t group_generation);
373
374
375 /**
376  * Remove a member from the group.  Note that this will NOT generate any
377  * PSYC traffic, it will merely update the local data base to modify
378  * how we react to 'membership test' queries.  The channel still needs to
379  * explicitly transmit a 'leave' message to notify other group members
380  * and they then also must still call this function in their respective
381  * methods handling the 'leave' message.  This way, how 'join' and 'leave'
382  * operations are exactly implemented is still up to the application;
383  * for example, there might be a 'leave_all' message to kick out everyone.
384  *
385  * Note that group members are explicitly trusted to perform these
386  * operations correctly; not doing so correctly will result in either
387  * denying members access or offering access to group data to
388  * non-members.
389  *
390  * @param group group handle
391  * @param member which peer to remove
392  * @param message_id message ID for the message that changed the membership
393  * @param group_generation the generation ID where the change went into effect
394  */
395 void
396 GNUNET_PSYC_group_member_remove (struct GNUNET_PSYC_Group *group,
397                                  const struct GNUNET_PeerIdentity *member,
398                                  uint64_t message_id,
399                                  uint64_t group_generation);
400
401
402 /**
403  * Function called to inform a member about state changes for a
404  * channel.  Note that (for sets) only the delta is communicated, not
405  * the full state.
406  *
407  * @param cls closure
408  * @param full_state_name full name of the state
409  * @param type how to interpret the change
410  * @param state_value information about the new state
411  * @param state_value_size number of bytes in 'state_value'
412  */
413 typedef void (*GNUNET_PSYC_StateCallback)(void *cls,
414                                           const char *full_state_name,
415                                           enum GNUNET_PSYC_Operator type,
416                                           const void *state_value,
417                                           size_t state_value_size);
418
419
420 /**
421  * Descriptor for an event handler handling PSYC state updates.
422  */
423 struct GNUNET_PSYC_StateHandler
424 {
425
426   /**
427    * Name of the state this handler calls about, used in try-and-slice matching.
428    */
429   const char *state_name;
430
431   /**
432    * Function to call whenever the respective state changes.
433    */
434   GNUNET_PSYC_StateCallback event_handler;
435
436   /**
437    * Closure for the 'event_handler' function.
438    */
439   void *event_handler_cls;
440
441 };
442
443
444 /**
445  * Join a PSYC group.  The entity joining is always the local peer.
446  * The user must immediately use the 'GNUNET_PSYC_member_send_to_host'
447  * (and possibly 'GNUNET_PSYC_member_host_variable_set') functions to
448  * transmit a 'join_msg' to the channel; if the join request succeeds,
449  * the channel state (and 'recent' method calls) will be replayed to
450  * the joining member.  There is no explicit notification on failure
451  * (as the channel may simply take days to approve, and disapproval is
452  * simply being ignored).
453  *
454  * @param cfg configuration to use
455  * @param pub_key ECC key that identifies the channel we wish to join
456  * @param method function to invoke on messages received from the channel,
457  *                typcially at least contains functions for 'join' and 'leave'.
458  * @param method_cls closure for 'method'
459  * @param state_count number of state handlers
460  * @param state_handlers array of state event handlers
461  * @return handle for the member, NULL on error 
462  */
463 struct GNUNET_PSYC_Member *
464 GNUNET_PSYC_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, 
465                          const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
466                          GNUNET_PSYC_Method method,
467                          void *method_cls,
468                          unsigned int state_count,
469                          struct GNUNET_PSYC_StateHandler *state_handlers);
470
471
472 /**
473  * Leave a multicast group.  Will terminate the connection to the PSYC
474  * service.  Polite clients should first explicitly send a 'leave'
475  * request (via 'GNUNET_PSYC_member_send_to_host').  
476  *
477  * @param member membership handle
478  */
479 void
480 GNUNET_PSYC_member_leave (struct GNUNET_PSYC_Member *member);
481
482
483 /**
484  * Function called to provide data for a transmission to the channel
485  * owner (aka the 'host' of the channel).  Note that returning
486  * GNUNET_OK or GNUNET_SYSERR (but not GNUNET_NO) invalidates the
487  * respective transmission handle.
488  *
489  * @param cls closure
490  * @param data_size initially set to the number of bytes available in 'data',
491  *        should be set to the number of bytes written to data (IN/OUT)
492  * @param data where to write the body of the message to give to the method;
493  *        function must copy at most '*data_size' bytes to 'data'.
494  * @return GNUNET_SYSERR on error (fatal, aborts transmission)
495  *         GNUNET_NO on success, if more data is to be transmitted later
496  *         GNUNET_YES if this completes the transmission (all data supplied)
497  */
498 typedef int (*GNUNET_PSYC_OriginReadyNotify)(void *cls,
499                                              size_t *data_size,
500                                              char *data);
501
502
503 /**
504  * Handle for a pending PSYC transmission operation.
505  */
506 struct GNUNET_PSYC_OriginTransmitHandle;
507
508
509 /**
510  * Request a message to be sent to the channel origin.
511  *
512  * @param member membership handle
513  * @param method_name which (PSYC) method should be invoked (on host)
514  * @param notify function to call when we are allowed to transmit (to get data)
515  * @param notify_cls closure for 'notify'
516  * @return transmission handle, NULL on error (i.e. more than one request queued)
517  */
518 struct GNUNET_PSYC_OriginTransmitHandle *
519 GNUNET_PSYC_member_send_to_origin (struct GNUNET_PSYC_Member *member,
520                                    const char *method_name,
521                                    GNUNET_PSYC_OriginReadyNotify notify,
522                                    void *notify_cls);
523
524
525 /**
526  * Set a (temporary, ":") variable for the next message being transmitted
527  * via 'GNUNET_PSYC_member_send_to_host'. If 'GNUNET_PSYC_member_send_to_host'
528  * is called and then cancelled, all variables that were set using this
529  * function will be unset (lost/forgotten).  To clear a variable state after
530  * setting it, you can also call this function again with NULL/0 for the value.
531  *
532  * @param member membership handle
533  * @param variable_name name of the variable to set
534  * @param value value to set for the given variable
535  * @param value_size number of bytes in 'value'
536  */
537 uint64_t
538 GNUNET_PSYC_member_origin_variable_set (struct GNUNET_PSYC_Member *member,
539                                         const char *variable_name,
540                                         const void *value,
541                                         size_t value_size);
542
543
544 /**
545  * Abort transmission request to origin.
546  *
547  * @param th handle of the request that is being aborted
548  */
549 void
550 GNUNET_PSYC_member_send_to_origin_cancel (struct GNUNET_PSYC_OriginTransmitHandle *th);
551
552
553 /**
554  * Handle to a story telling operation.
555  */
556 struct GNUNET_PSYC_Story;
557
558
559 /**
560  * Request to be told the message history of the channel.  Historic
561  * messages (but NOT the state at the time) will be replayed (given to
562  * the normal method handlers) if available and if access is
563  * permitted.
564  *
565  * @param member which channel should be replayed?
566  * @param start earliest interesting point in history
567  * @param end last (exclusive) interesting point in history
568  * @param method function to invoke on messages received from the story
569  * @param method_cls closure for 'method'
570  * @param finish_cb function to call when the requested story has been fully 
571  *        told (counting message IDs might not suffice, as some messages
572  *        might be secret and thus the listener would not know the story is 
573  *        finished without being told explicitly); once this function
574  *        has been called, the client must not call
575  *        'GNUNET_PSYC_member_story_tell_cancel' anymore
576  * @param finish_cb_cls closure to finish_cb
577  * @return handle to cancel story telling operation
578  */
579 struct GNUNET_PSYC_Story *
580 GNUNET_PSYC_member_story_tell (struct GNUNET_PSYC_Member *member,
581                                uint64_t start,
582                                uint64_t end,
583                                GNUNET_PSYC_Method method,
584                                void *method_cls,
585                                void (*finish_cb)(void *),
586                                void *finish_cb_cls);
587
588
589 /**
590  * Abort story telling.  This function must not be called from within
591  * method handlers (as given to 'GNUNET_PSYC_member_join') of the
592  * member.
593  *
594  * @param story story telling operation to stop
595  */
596 void
597 GNUNET_PSYC_member_story_tell_cancel (struct GNUNET_PSYC_Story *story);
598
599
600 /**
601  * Call the given callback on all matching values (including
602  * variables) in the channel state.  The callback is invoked
603  * synchronously on all matching states (as the state is fully
604  * replicated in the library in this process; channel states should be
605  * small, large data is to be passed as streaming data to methods).
606  *
607  * A name matches if it includes the 'state_name' prefix, thus
608  * requesting the empty state ("") will match all values; requesting
609  * "a_b" will also return values stored under "a_b_c".
610  *
611  * @param member membership handle
612  * @param state_name name of the state to query (full name 
613  *        might be longer, this is only the prefix that must match)
614  * @param cb function to call on the matching state values
615  * @param cb_cls closure for 'cb'
616  * @return message ID for which the state was returned (last seen
617  *         message ID)
618  */
619 uint64_t
620 GNUNET_PSYC_member_state_get_all (struct GNUNET_PSYC_Member *member,
621                                   const char *state_name,
622                                   GNUNET_PSYC_StateCallback cb,
623                                   void *cb_cls);
624
625
626 /**
627  * Obtain the current value of the best-matching value in the state
628  * (including variables).  Note that variables are only valid during a
629  * GNUNET_PSYC_Method invocation, as variables are only valid for the
630  * duration of a method invocation.  
631  *
632  * If the requested variable name does not have an exact state in
633  * the state, the nearest less-specific name is matched; for example,
634  * requesting "a_b" will match "a" if "a_b" does not exist.
635  *
636  * @param member membership handle
637  * @param variable_name name of the variable to query 
638  * @param return_value_size set to number of bytes in variable, 
639  *        needed as variables might contain binary data and
640  *        might also not be 0-terminated; set to 0 on errors
641  * @return NULL on error (no matching state or variable), pointer
642           to the respective value otherwise
643  */
644 const void *
645 GNUNET_PSYC_member_state_get (struct GNUNET_PSYC_Member *member,
646                               const char *variable_name,
647                               size_t *return_value_size);
648
649
650
651 #if 0                           /* keep Emacsens' auto-indent happy */
652 {
653 #endif
654 #ifdef __cplusplus
655 }
656 #endif
657
658 /* ifndef GNUNET_PSYC_SERVICE_H */
659 #endif
660 /* end of gnunet_psyc_service.h */