-further refinements to the APIs for PSYC/multicast
[oweals/gnunet.git] / src / include / gnunet_multicast_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_multicast_service.h
23  * @brief multicast service; establish tunnels to distant peers
24  * @author Christian Grothoff
25  */
26
27 #ifndef GNUNET_MULTICAST_SERVICE_H
28 #define GNUNET_MULTICAST_SERVICE_H
29
30 #ifdef __cplusplus
31 extern "C"
32 {
33 #if 0                           /* keep Emacsens' auto-indent happy */
34 }
35 #endif
36 #endif
37
38 #include "gnunet_util_lib.h"
39 #include "gnunet_transport_service.h"
40
41 /**
42  * Version number of GNUnet-multicast API.
43  */
44 #define GNUNET_MULTICAST_VERSION 0x00000000
45
46
47 /**
48  * Opaque handle for a multicast group member.
49  */
50 struct GNUNET_MULTICAST_Member;
51
52 /**
53  * Handle for the origin of a multicast group.
54  */
55 struct GNUNET_MULTICAST_Origin;
56
57 /**
58  * Group membership policies.
59  */
60 enum GNUNET_MULTICAST_JoinPolicy
61 {
62   /**
63    * Anyone can join the group, without announcing his presence; all
64    * messages are always public and can be distributed freely.  Joins
65    * may be announced, but this is not required.
66    */
67   GNUNET_MULTICAST_JP_ANONYMOUS = 0,
68
69   /**
70    * Origin must approve membership to the group, messages must only be
71    * distributed to current group members.  This includes the group
72    * state as well as transient messages.
73    */
74   GNUNET_MULTICAST_JP_PRIVATE = 1
75
76 #if IDEAS_FOR_FUTURE
77   /**
78    * Anyone can freely join the group (no approval required); however,
79    * transient messages must only be distributed to current group
80    * members, so the origin must still acknowledge that the member
81    * joined before transient messages are delivered.  As approval is
82    * guaranteed, the presistent group state can de synchronized freely
83    * immediately, prior to origin confirmation
84    */
85   GNUNET_MULTICAST_JP_OPEN = 2
86 #endif
87
88 };
89
90
91 /**
92  * Opaque handle to a replay request from the multicast service.
93  */
94 struct GNUNET_MULTICAST_ReplayHandle;
95
96
97 /**
98  * Functions with this signature are called whenever the multicast
99  * service needs a message to be replayed.  Implementations of this
100  * function MUST call 'GNUNET_MULTICAST_replay' ONCE (with a message
101  * or an error); however, if the origin is destroyed or the group is
102  * left, the replay handle must no longer be used.
103  *
104  * @param cls closure (set from GNUNET_MULTICAST_origin_start/join)
105  * @param message_id which message should be replayed
106  * @param rh handle to pass to message transmit function
107  */
108 typedef void (*GNUNET_MULTICAST_ReplayCallback) (void *cls,
109                                                  uint64_t message_id,
110                                                  struct GNUNET_MULTICAST_ReplayHandle *rh);
111
112
113 /**
114  * Possible error codes during replay.
115  */
116 enum GNUNET_MULTICAST_ReplayErrorCode
117 {
118   
119   /**
120    * Everything is fine.
121    */ 
122   GNUNET_MULTICAST_REC_OK = 0,
123
124   /**
125    * Message has been discarded (likely transient message that was too old).
126    */ 
127   GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1,
128
129   /**
130    * Message ID counter was larger than the highest counter this
131    * replay function has ever encountered; thus it is likely the
132    * origin never sent it and we're at the HEAD of the multicast
133    * stream as far as this node is concerned.
134    */ 
135   GNUNET_MULTICAST_REC_PAST_HEAD = 2,
136
137   /**
138    * Internal error (i.e. database error).  Try some other peer.
139    */ 
140   GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3
141
142 };
143
144
145 GNUNET_NETWORK_STRUCT_BEGIN
146
147 /**
148  * Header of a multicast message.  This format is public as the replay
149  * mechanism must replay messages using the same format.  This is
150  * needed as we want to integrity-check messages within the multicast
151  * layer to avoid multicasting mal-formed messages.
152  */
153 struct GNUNET_MULTICAST_MessageHeader
154 {
155
156   /**
157    * Header for all multicast messages from the origin.
158    */
159   struct GNUNET_MessageHeader header;
160
161   /**
162    * How many hops has this message taken since the origin?
163    * (helpful to determine shortest paths to the origin for responses
164    *  among honest peers; updated at each hop and thus not signed
165    *  and not secure)
166    */
167   uint32_t hop_counter GNUNET_PACKED;
168
169   /**
170    * ECC signature of the message.  Signature must match the public
171    * key of the multicast group.
172    */
173   struct GNUNET_CRYPTO_EccSignature signature;
174
175   /**
176    * Signature of the multicast message.
177    */
178   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
179
180   /**
181    * Number of the message, monotonically increasing.
182    */
183   uint64_t message_id GNUNET_PACKED;
184
185   /**
186    * Counter that monotonically increases whenever a member
187    * leaves the group.
188    */
189   uint64_t group_generation GNUNET_PACKED;
190
191   /**
192    * Difference between the current message_id and the message_id of
193    * the preceeding non-transient message.  Zero for transient
194    * messages, UINT64_MAX for the first message, or any other message
195    * creating a full state reset by the origin.  By subtracting
196    * 'state_delta' from 'message_id', it is possible to calculate the
197    * message ID of the preceeding non-transient message and thus
198    * quickly traverse all state changes up to the last full state
199    * reset by the origin.  This is useful as it allows joining clients
200    * to quickly reassemble the state while skipping over transient
201    * messages (and doing so without having to trust intermediaries to
202    * do it right, as the indices in the chain are signed).  If the
203    * state chain is getting too long, the origin can choose to
204    * originate a state message with a state_delta of UINT64_MAX,
205    * thereby starting a new chain.  The origin will then have to
206    * re-create the full state with state update messages following the
207    * state reset message.
208    *
209    * Open question: needed in multicast, or just have this in PSYC;
210    * still might be useful for selective fetching of messages.
211    * Still, that again should that not be done by PSYC?
212    */
213   uint64_t state_delta GNUNET_PACKED;
214
215   /**
216    * Header for the message body.  Three message types are
217    * specifically understood by multicast, namely "peer join", "peer
218    * leave", and "group terminated".  Multicast will use those
219    * messages to update its list of candidates for content
220    * distribution.  All other message types are application-specific.
221    */
222   struct GNUNET_MessageHeader body;
223
224   /* followed by message body */
225 };
226
227 GNUNET_NETWORK_STRUCT_END
228
229
230 /**
231  * Replay a message from the multicast group.
232  *
233  * @param rh replay handle identifying which replay operation was requested
234  * @param msg replayed message, NULL if unknown/error
235  * @param ec error code
236  */
237 void
238 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
239                          const struct GNUNET_MULTICAST_MessageHeader *msg,
240                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
241
242
243 /**
244  * Handle that identifies a join request (to match calls to the
245  * 'GNUNET_MULTICAST_MembershipChangeCallback' to the corresponding
246  * calls to 'GNUNET_MULTICAST_join_decision').
247  */
248 struct GNUNET_MULTICAST_JoinHande;
249
250
251 /**
252  * Function to call with the decision made for a membership change
253  * request.  Must be called once and only once in response to an
254  * invocation of the 'GNUNET_MULTICAST_MembershipChangeCallback'.
255  *
256  * @param jh join request handle
257  * @param join_response message to send in response to the joining peer;
258  *        can also be used to redirect the peer to a different group at the
259  *        application layer; this response is to be transmitted to the
260  *        peer that issued the request even if admission is denied.
261  * @param is_admitted GNUNET_OK if joining is approved, GNUNET_SYSERR if it is disapproved;
262  *         GNUNET_NO for peers leaving 
263  * @param relay_count number of relays given
264  * @param relays array of suggested peers that might be useful relays to use
265  *        when joining the multicast group (essentially a list of peers that
266  *        are already part of the multicast group and might thus be willing
267  *        to help with routing).  If empty, only this local peer (which must
268  *        be the multicast origin) is a good candidate for building the
269  *        multicast tree.  Note that it is unnecessary to specify our own
270  *        peer identity in this array.
271  */
272 void
273 GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
274                                 const struct GNUNET_MessageHeader *join_response,
275                                 int is_admitted,
276                                 unsigned int relay_count,
277                                 const struct GNUNET_PeerIdentity *relays);
278
279
280 /**
281  * Method called whenever another peer wants to join or has left a 
282  * multicast group.  Implementations of this function must call
283  * 'GNUNET_MULTICAST_join_decision' with the decision.
284  *
285  * @param cls closure
286  * @param peer identity of the peer that wants to join or leave
287  * @param join_req application-dependent join message from the new user
288  *        (might, for example, contain a user 
289  *        bind user identity/pseudonym to peer identity, application-level
290  *        message to origin, etc.)
291  * @param is_joining GNUNET_YES if the peer wants to join, GNUNET_NO if the peer left
292  * @param jh join handle to pass to 'GNUNET_MULTICAST_join_decison'
293  */
294 typedef void (*GNUNET_MULTICAST_MembershipChangeCallback)(void *cls,
295                                                           const struct GNUNET_PeerIdentity *peer,
296                                                           const struct GNUNET_MessageHeader *join_req,
297                                                           int is_joining,
298                                                           struct GNUNET_MULTICAST_JoinHandle *jh);
299
300
301 /**
302  * Method called to test if a member was in the group at a particular time.
303  *
304  * FIXME: maybe allow reply to be asynchronous
305  *
306  * @param cls closure
307  * @param peer identity of the peer that we want to test
308  * @param message_id message ID for which we want to do the test
309  * @return GNUNET_YES if peer was a member, GNUNET_NO if peer was not a member,
310  *         GNUNET_SYSERR if we cannot answer the membership test
311  */
312 typedef int (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
313                                                        const struct GNUNET_PeerIdentity *peer,
314                                                        uint64_t message_id);
315
316
317 /**
318  * Function called whenever a group member has transmitted a message
319  * to the origin (other than joining or leaving).
320  *
321  * @param cls closure (set from GNUNET_MULTICAST_origin_start)
322  * @param sender identity of the sender
323  * @param response_id unique counter for the response from this sender to this origin
324  * @param msg message to the origin
325  */
326 typedef void (*GNUNET_MULTICAST_ResponseCallback) (void *cls,
327                                                    const struct GNUNET_PeerIdentity *sender,
328                                                    uint64_t response_id,
329                                                    const struct GNUNET_MessageHeader *msg);
330
331
332 /**
333  * Function called whenever a group member is receiving a message from
334  * the origin.  If admission to the group is denied, this function is
335  * called once with the response of the 'origin' (as given to 
336  * 'GNUNET_MULTICAST_join_decision') and then a second time with "NULL"
337  * to indicate that the connection failed for good.
338  *
339  * @param cls closure (set from GNUNET_MULTICAST_member_join)
340  * @param message_id unique number of the message, 0 for response to join request,
341  *        normal message IDs in either direction start at 1.
342  * @param msg message from the origin, NULL if the origin shut down
343  *        (or we were kicked out, and we should thus call GNUNET_MULTICAST_member_leave next)
344  */
345 typedef void (*GNUNET_MULTICAST_MulticastMessageCallback) (void *cls,
346                                                            uint64_t message_id,
347                                                            const struct GNUNET_MULTICAST_MessageHeader *msg);
348
349
350 /**
351  * Start a multicast group.  Will advertise the origin in the P2P
352  * overlay network under the respective public key so that other peer
353  * can find this peer to join it.  Peers that issue
354  * 'GNUNET_MULTICAST_member_join' can then transmit a join request to
355  * either an existing group member (if the 'join_policy' is
356  * permissive) or to the origin.  If the joining is approved, the
357  * member is cleared for 'replay' and will begin to receive messages
358  * transmitted to the group.  If joining is disapproved, the failed
359  * candidate will be given a response.  Members in the group can send
360  * messages to the origin (one at a time).
361  *
362  * @param cfg configuration to use
363  * @param cls closure for the various callbacks that follow
364  * @param priv_key ECC key that will be used to sign messages for this
365  *                 multicast session; public key is used to identify the
366  *                 multicast group; FIXME: we'll likely want to use
367  *                 NOT the p521 curve here, but a cheaper one in the future
368  * @param join_policy what is the membership policy of the group?
369  * @param replay_cb function that can be called to replay a message
370  * @param test_cb function multicast can use to test group membership
371  * @param join_cb function called to approve / disapprove joining of a peer
372  * @param response_cb function called with messages from group members
373  * @return handle for the origin, NULL on error 
374  */
375 struct GNUNET_MULTICAST_Origin *
376 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 
377                                void *cls,
378                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
379                                enum GNUNET_MULTICAST_JoinPolicy join_policy,
380                                GNUNET_MULITCAST_ReplayCallback replay_cb,
381                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
382                                GNUNET_MULTICAST_MembershipChangeCallback join_cb,
383                                GNUNET_MULTICAST_ResponseCallback response_cb);
384
385
386 /**
387  * Handle for a request to send a message to all multicast group members
388  * (from the origin).
389  */
390 struct GNUNET_MULTICAST_MulticastRequest;
391
392
393 /**
394  * Send a message to the multicast group.
395  *
396  * @param origin handle to the multicast group
397  * @param size number of bytes to transmit
398  * @param cb function to call to get the message
399  * @param cb_cls closure for 'cb'
400  * @return NULL on error (i.e. request already pending)
401  */
402 struct GNUNET_MULTICAST_MulticastRequest *
403 GNUNET_MULTICAST_origin_send_to_all (struct GNUNET_MULTICAST_Origin *origin,
404                                      size_t size,
405                                      GNUNET_CONNECTION_TransmitReadyNotify cb,
406                                      void *cb_cls);
407
408
409 /**
410  * Cancel request for message transmission to multicast group.
411  *
412  * @param mr request to cancel
413  */
414 void
415 GNUNET_MULTICAST_origin_send_to_all_cancel (struct GNUNET_MULTICAST_MulticastRequest *mr);
416
417
418 /**
419  * End a multicast group.
420  *
421  * @param origin multicast group to terminate
422  */
423 void
424 GNUNET_MULTICAST_origin_end (struct GNUNET_MULTICAST_Origin *origin);
425
426
427 /**
428  * Join a multicast group.  The entity joining is always the local
429  * peer.  Further information about the candidate can be provided in
430  * the 'join_req' message.  If the join fails, the 'message_cb' is
431  * invoked with a (failure) response and then with 'NULL'.  If the
432  * join succeeds, outstanding (state) messages and ongoing multicast
433  * messages will be given to the 'message_cb' until the member decides
434  * to leave the group.  The 'test_cb' and 'replay_cb' functions may be
435  * called at anytime by the multicast service to support relaying
436  * messages to other members of the group.
437  *
438  * @param cfg configuration to use
439  * @param cls closure for callbacks
440  * @param pub_key ECC key that identifies the group
441  * @param max_known_message_id largest known message ID to the replay service;
442  *        all messages with IDs larger than this ID will be replayed if
443  *        possible (lower IDs will be considered known and thus only
444  *        be replayed upon explicit request)
445  * @param max_known_state_message_id largest known message ID with a non-zero
446  *                       value for the 'state_delta'; state messages with
447  *        larger IDs than this value will be replayed with high priority
448  *        (lower IDs will be considered known and thus only
449  *        be replayed upon explicit request)
450  * @param replay_cb function that can be called to replay messages
451  *        this peer already knows from this group; NULL if this
452  *        client is unable to support replay
453  * @param test_cb function multicast can use to test group membership
454  * @param message_cb function to be called for all messages we 
455  *        receive from the group, excluding those our replay_cb
456  *        already has
457  * @param join_req application-dependent join message to be passed to origin
458  *        (might, for example, contain a user 
459  *        bind user identity/pseudonym to peer identity, application-level
460  *        message to origin, etc.)
461  * @return handle for the member, NULL on error 
462  */
463 struct GNUNET_MULTICAST_Member *
464 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, 
465                               void *cls,
466                               const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
467                               uint64_t max_known_message_id,
468                               uint64_t max_known_state_message_id,
469                               GNUNET_MULTICAST_ReplayCallback replay_cb,
470                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
471                               GNUNET_MULTICAST_MulticastMessageCallback message_cb,
472                               const struct GNUNET_MessageHeader *join_req);
473
474
475 /**
476  * Handle for a replay request.
477  */
478 struct GNUNET_MULTICAST_ReplayRequest;
479
480
481 /**
482  * Request a message to be replayed.  Useful if messages below
483  * the 'max_known_*_id's given when joining are needed and not
484  * known to the client.
485  *
486  * @param member membership handle
487  * @param message_id ID of a message that this client would like to see replayed
488  * @param message_cb function to be called for the replayed message
489  * @param message_cb_cls closure for 'message_cb'
490  * @return replay request handle, NULL on error
491  */
492 struct GNUNET_MULTICAST_ReplayRequest *
493 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
494                                         uint64_t message_id,
495                                         GNUNET_MULTICAST_MulticastMessageCallback message_cb,
496                                         void *message_cb_cls);
497
498
499 /**
500  * Cancel a replay request.
501  *
502  * @param rr request to cancel
503  */
504 void
505 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_ReplayRequest *rr);
506
507
508 /**
509  * Leave a mutlicast group.
510  *
511  * @param member membership handle
512  */
513 void
514 GNUNET_MULTICAST_member_leave (struct GNUNET_MULTICAST_Member *member);
515
516
517 /**
518  * Handle for a message to be delivered to the origin.
519  */
520 struct GNUNET_MULTICAST_ResponseRequest;
521
522
523 /**
524  * Send a message to the origin of the multicast group.  
525  * 
526  * @param member membership handle
527  * @param size number of bytes we want to send to origin
528  * @param cb callback to call to get the message
529  * @param cb_cls closure for 'cb'
530  * @return handle to cancel request, NULL on error (i.e. request already pending)
531  */
532 struct GNUNET_MULTICAST_ResponseRequest *
533 GNUNET_MULTICAST_member_message_to_origin (struct GNUNET_MULTICAST_Member *member,
534                                            size_t size,
535                                            GNUNET_CONNECTION_TransmitReadyNotify cb,
536                                            void *cb_cls);
537
538
539 /**
540  * Cancel request for message transmission to origin.
541  *
542  * @param rr request to cancel
543  */
544 void
545 GNUNET_MULTICAST_member_message_to_origin_cancel (struct GNUNET_MULTICAST_ResponseRequest *rr);
546
547
548
549 #if 0                           /* keep Emacsens' auto-indent happy */
550 {
551 #endif
552 #ifdef __cplusplus
553 }
554 #endif
555
556 /* ifndef GNUNET_MULTICAST_SERVICE_H */
557 #endif
558 /* end of gnunet_multicast_service.h */