-more work on multicast/psyc API designs
[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   uint64_t state_delta GNUNET_PACKED;
210
211   /**
212    * Header for the message body.  Three message types are
213    * specifically understood by multicast, namely "peer join", "peer
214    * leave", and "group terminated".  Multicast will use those
215    * messages to update its list of candidates for content
216    * distribution.  All other message types are application-specific.
217    */
218   struct GNUNET_MessageHeader body;
219
220   /* followed by message body */
221 };
222
223 GNUNET_NETWORK_STRUCT_END
224
225
226 /**
227  * Replay a message from the multicast group.
228  *
229  * @param rh replay handle identifying which replay operation was requested
230  * @param msg replayed message, NULL if unknown/error
231  * @param ec error code
232  */
233 void
234 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
235                          const struct GNUNET_MULTICAST_MessageHeader *msg,
236                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
237
238
239 /**
240  * Handle that identifies a join request (to match calls to the
241  * 'GNUNET_MULTICAST_MembershipChangeCallback' to the corresponding
242  * calls to 'GNUNET_MULTICAST_join_decision').
243  */
244 struct GNUNET_MULTICAST_JoinHande;
245
246
247 /**
248  * Function to call with the decision made for a membership change
249  * request.  Must be called once and only once in response to an
250  * invocation of the 'GNUNET_MULTICAST_MembershipChangeCallback'.
251  *
252  * @param jh join request handle
253  * @param join_response message to send in response to the joining peer;
254  *        can also be used to redirect the peer to a different group at the
255  *        application layer; this response is to be transmitted to the
256  *        peer that issued the request even if admission is denied.
257  * @param is_admitted GNUNET_OK if joining is approved, GNUNET_SYSERR if it is disapproved;
258  *         GNUNET_NO for peers leaving 
259  * @param relay_count number of relays given
260  * @param relays array of suggested peers that might be useful relays to use
261  *        when joining the multicast group (essentially a list of peers that
262  *        are already part of the multicast group and might thus be willing
263  *        to help with routing).  If empty, only this local peer (which must
264  *        be the multicast origin) is a good candidate for building the
265  *        multicast tree.  Note that it is unnecessary to specify our own
266  *        peer identity in this array.
267  */
268 void
269 GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
270                                 const struct GNUNET_MessageHeader *join_response,
271                                 int is_admitted,
272                                 unsigned int relay_count,
273                                 const struct GNUNET_PeerIdentity *relays);
274
275
276 /**
277  * Method called whenever another peer wants to join or has left a 
278  * multicast group.  Implementations of this function must call
279  * 'GNUNET_MULTICAST_join_decision' with the decision.
280  *
281  * @param cls closure
282  * @param peer identity of the peer that wants to join or leave
283  * @param join_req application-dependent join message from the new user
284  *        (might, for example, contain a user 
285  *        bind user identity/pseudonym to peer identity, application-level
286  *        message to origin, etc.)
287  * @param is_joining GNUNET_YES if the peer wants to join, GNUNET_NO if the peer left
288  * @param jh join handle to pass to 'GNUNET_MULTICAST_join_decison'
289  */
290 typedef int (*GNUNET_MULTICAST_MembershipChangeCallback)(void *cls,
291                                                          const struct GNUNET_PeerIdentity *peer,
292                                                          const struct GNUNET_MessageHeader *join_req,
293                                                          int is_joining,
294                                                          struct GNUNET_MULTICAST_JoinHandle *jh);
295
296
297 /**
298  * Method called to test if a member was in the group at a particular time.
299  *
300  * @param cls closure
301  * @param peer identity of the peer that we want to test
302  * @param message_id message ID for which we want to do the test
303  * @param group_generation the generation of the group for which we want to do the test
304  * @return GNUNET_YES if peer was a member, GNUNET_NO if peer was not a member,
305  *         GNUNET_SYSERR if we cannot answer the membership test
306  */
307 typedef int (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
308                                                        const struct GNUNET_PeerIdentity *peer,
309                                                        uint64_t message_id,
310                                                        uint64_t group_generation);
311
312
313 /**
314  * Function called whenever a group member has transmitted a message
315  * to the origin (other than joining or leaving).
316  *
317  * @param cls closure (set from GNUNET_MULTICAST_origin_start)
318  * @param sender identity of the sender
319  * @param response_id unique counter for the response from this sender to this origin
320  * @param msg message to the origin
321  */
322 typedef void (*GNUNET_MULTICAST_ResponseCallback) (void *cls,
323                                                    const struct GNUNET_PeerIdentity *sender,
324                                                    uint64_t response_id,
325                                                    const struct GNUNET_MessageHeader *msg);
326
327
328 /**
329  * Function called whenever a group member is receiving a message from
330  * the origin.  If admission to the group is denied, this function is
331  * called once with the response of the 'origin' (as given to 
332  * 'GNUNET_MULTICAST_join_decision') and then a second time with "NULL"
333  * to indicate that the connection failed for good.
334  *
335  * @param cls closure (set from GNUNET_MULTICAST_member_join)
336  * @param message_id unique number of the message
337  * @param msg message from the origin, NULL if the origin shut down
338  *        (or we were kicked out, and we should thus call GNUNET_MULTICAST_member_leave next)
339  */
340 typedef void (*GNUNET_MULTICAST_MessageCallback) (void *cls,
341                                                   uint64_t message_id,
342                                                   const struct GNUNET_MULTICAST_MessageHeader *msg);
343
344
345 /**
346  * Start a multicast group.  Will advertise the origin in the P2P
347  * overlay network under the respective public key so that other peer
348  * can find this peer to join it.  Peers that issue
349  * 'GNUNET_MULTICAST_member_join' can then transmit a join request to
350  * either an existing group member (if the 'join_policy' is
351  * permissive) or to the origin.  If the joining is approved, the
352  * member is cleared for 'replay' and will begin to receive messages
353  * transmitted to the group.  If joining is disapproved, the failed
354  * candidate will be given a response.  Members in the group can send
355  * messages to the origin (one at a time).
356  *
357  * @param cfg configuration to use
358  * @param cls closure for the various callbacks that follow
359  * @param priv_key ECC key that will be used to sign messages for this
360  *                 multicast session; public key is used to identify the
361  *                 multicast group; FIXME: we'll likely want to use
362  *                 NOT the p521 curve here, but a cheaper one in the future
363  * @param join_policy what is the membership policy of the group?
364  * @param replay_cb function that can be called to replay a message
365  * @param test_cb function multicast can use to test group membership
366  * @param join_cb function called to approve / disapprove joining of a peer
367  * @param response_cb function called with messages from group members
368  * @return handle for the origin, NULL on error 
369  */
370 struct GNUNET_MULTICAST_Origin *
371 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 
372                                void *cls,
373                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
374                                enum GNUNET_MULTICAST_JoinPolicy join_policy,
375                                GNUNET_MULITCAST_ReplayCallback replay_cb,
376                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
377                                GNUNET_MULTICAST_MembershipChangeCallback join_cb,
378                                GNUNET_MULTICAST_ResponseCallback response_cb);
379
380
381 /**
382  * Handle for a request to send a message to all multicast group members
383  * (from the origin).
384  */
385 struct GNUNET_MULTICAST_MulticastRequest;
386
387
388 /**
389  * Send a message to the multicast group.
390  *
391  * @param origin handle to the multicast group
392  * @param size number of bytes to transmit
393  * @param cb function to call to get the message
394  * @param cb_cls closure for 'cb'
395  * @return NULL on error (i.e. request already pending)
396  */
397 struct GNUNET_MULTICAST_MulticastRequest *
398 GNUNET_MULTICAST_origin_send_to_all (struct GNUNET_MULTICAST_Origin *origin,
399                                      size_t size,
400                                      GNUNET_CONNECTION_TransmitReadyNotify cb,
401                                      void *cb_cls);
402
403
404 /**
405  * Cancel request for message transmission to multicast group.
406  *
407  * @param mr request to cancel
408  */
409 void
410 GNUNET_MULTICAST_origin_send_to_all_cancel (struct GNUNET_MULTICAST_MulticastRequest *mr);
411
412
413 /**
414  * End a multicast group.
415  *
416  * @param origin multicast group to terminate
417  */
418 void
419 GNUNET_MULTICAST_origin_end (struct GNUNET_MULTICAST_Origin *origin);
420
421
422 /**
423  * Join a multicast group.  The entity joining is always the local
424  * peer.  Further information about the candidate can be provided in
425  * the 'join_req' message.  If the join fails, the 'message_cb' is
426  * invoked with a (failure) response and then with 'NULL'.  If the
427  * join succeeds, outstanding (state) messages and ongoing multicast
428  * messages will be given to the 'message_cb' until the member decides
429  * to leave the group.  The 'test_cb' and 'replay_cb' functions may be
430  * called at anytime by the multicast service to support relaying
431  * messages to other members of the group.
432  *
433  * @param cfg configuration to use
434  * @param cls closure for callbacks
435  * @param pub_key ECC key that identifies the group
436  * @param max_known_message_id largest known message ID to the replay service;
437  *        all messages with IDs larger than this ID will be replayed if
438  *        possible (lower IDs will be considered known and thus only
439  *        be replayed upon explicit request)
440  * @param max_known_state_message_id largest known message ID with a non-zero
441  *                       value for the 'state_delta'; state messages with
442  *        larger IDs than this value will be replayed with high priority
443  *        (lower IDs will be considered known and thus only
444  *        be replayed upon explicit request)
445  * @param replay_cb function that can be called to replay messages
446  *        this peer already knows from this group; NULL if this
447  *        client is unable to support replay
448  * @param test_cb function multicast can use to test group membership
449  * @param message_cb function to be called for all messages we 
450  *        receive from the group, excluding those our replay_cb
451  *        already has
452  * @param join_req application-dependent join message to be passed to origin
453  *        (might, for example, contain a user 
454  *        bind user identity/pseudonym to peer identity, application-level
455  *        message to origin, etc.)
456  * @return handle for the member, NULL on error 
457  */
458 struct GNUNET_MULTICAST_Member *
459 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, 
460                               void *cls,
461                               const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
462                               uint64_t max_known_message_id,
463                               uint64_t max_known_state_message_id,
464                               GNUNET_MULTICAST_ReplayCallback replay_cb,
465                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
466                               GNUNET_MULTICAST_MessageCallback message_cb,
467                               const struct GNUNET_MessageHeader *join_req);
468
469
470 /**
471  * Handle for a replay request.
472  */
473 struct GNUNET_MULTICAST_ReplayRequest;
474
475
476 /**
477  * Request a message to be replayed.  Useful if messages below
478  * the 'max_known_*_id's given when joining are needed and not
479  * known to the client.
480  *
481  * @param member membership handle
482  * @param message_id ID of a message that this client would like to see replayed
483  * @param message_cb function to be called for the replayed message
484  * @param message_cb_cls closure for 'message_cb'
485  * @return replay request handle, NULL on error
486  */
487 struct GNUNET_MULTICAST_ReplayRequest *
488 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
489                                         uint64_t message_id,
490                                         GNUNET_MULTICAST_MessageCallback message_cb,
491                                         void *message_cb_cls);
492
493
494 /**
495  * Cancel a replay request.
496  *
497  * @param rr request to cancel
498  */
499 void
500 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_ReplayRequest *rr);
501
502
503 /**
504  * Leave a mutlicast group.
505  *
506  * @param member membership handle
507  */
508 void
509 GNUNET_MULTICAST_member_leave (struct GNUNET_MULTICAST_Member *member);
510
511
512 /**
513  * Handle for a message to be delivered to the origin.
514  */
515 struct GNUNET_MULTICAST_ResponseRequest;
516
517
518 /**
519  * Send a message to the origin of the multicast group.  
520  * 
521  * @param member membership handle
522  * @param size number of bytes we want to send to origin
523  * @param cb callback to call to get the message
524  * @param cb_cls closure for 'cb'
525  * @return handle to cancel request, NULL on error (i.e. request already pending)
526  */
527 struct GNUNET_MULTICAST_ResponseRequest *
528 GNUNET_MULTICAST_member_message_to_origin (struct GNUNET_MULTICAST_Member *member,
529                                            size_t size,
530                                            GNUNET_CONNECTION_TransmitReadyNotify cb,
531                                            void *cb_cls);
532
533
534 /**
535  * Cancel request for message transmission to origin.
536  *
537  * @param rr request to cancel
538  */
539 void
540 GNUNET_MULTICAST_member_message_to_origin_cancel (struct GNUNET_MULTICAST_ResponseRequest *rr);
541
542
543
544 #if 0                           /* keep Emacsens' auto-indent happy */
545 {
546 #endif
547 #ifdef __cplusplus
548 }
549 #endif
550
551 /* ifndef GNUNET_MULTICAST_SERVICE_H */
552 #endif
553 /* end of gnunet_multicast_service.h */