psyc apis
[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  * Handle to pass back for the answer of a membership test.
303  */
304 struct GNUNET_MULTICAST_MembershipTestHandle;
305
306
307 /**
308  * Call informing multicast about the decision taken for membership test.
309  *
310  * @param mth handle that was given for the query
311  * @param decision GNUNET_YES if peer was a member, GNUNET_NO if peer was not a member,
312  *         GNUNET_SYSERR if we cannot answer the membership test
313  */
314 void
315 GNUNET_MULTICAST_membership_test_answer (struct GNUNET_MULTICAST_MembershipTestHandle *mth,
316                                          int decision);
317
318
319 /**
320  * Method called to test if a member was in the group at a particular time.
321  *
322  * @param cls closure
323  * @param peer identity of the peer that we want to test
324  * @param message_id message ID for which we want to do the test
325  * @param mth handle to give to 'GNUNET_MULTICAST_membership_test_answer'
326  */
327 typedef void (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
328                                                         const struct GNUNET_PeerIdentity *peer,
329                                                         uint64_t message_id,
330                                                         struct GNUNET_MULTICAST_MembershipTestHandle *mth);
331
332
333 /**
334  * Function called whenever a group member has transmitted a message
335  * to the origin (other than joining or leaving).
336  *
337  * @param cls closure (set from GNUNET_MULTICAST_origin_start)
338  * @param sender identity of the sender
339  * @param response_id unique counter for the response from this sender to this origin
340  * @param msg message to the origin
341  */
342 typedef void (*GNUNET_MULTICAST_ResponseCallback) (void *cls,
343                                                    const struct GNUNET_PeerIdentity *sender,
344                                                    uint64_t response_id,
345                                                    const struct GNUNET_MessageHeader *msg);
346
347
348 /**
349  * Function called whenever a group member is receiving a message from
350  * the origin.  If admission to the group is denied, this function is
351  * called once with the response of the 'origin' (as given to 
352  * 'GNUNET_MULTICAST_join_decision') and then a second time with "NULL"
353  * to indicate that the connection failed for good.
354  *
355  * @param cls closure (set from GNUNET_MULTICAST_member_join)
356  * @param message_id unique number of the message, 0 for response to join request,
357  *        normal message IDs in either direction start at 1.
358  * @param msg message from the origin, NULL if the origin shut down
359  *        (or we were kicked out, and we should thus call GNUNET_MULTICAST_member_leave next)
360  */
361 typedef void (*GNUNET_MULTICAST_MulticastMessageCallback) (void *cls,
362                                                            uint64_t message_id,
363                                                            const struct GNUNET_MULTICAST_MessageHeader *msg);
364
365
366 /**
367  * Start a multicast group.  Will advertise the origin in the P2P
368  * overlay network under the respective public key so that other peer
369  * can find this peer to join it.  Peers that issue
370  * 'GNUNET_MULTICAST_member_join' can then transmit a join request to
371  * either an existing group member (if the 'join_policy' is
372  * permissive) or to the origin.  If the joining is approved, the
373  * member is cleared for 'replay' and will begin to receive messages
374  * transmitted to the group.  If joining is disapproved, the failed
375  * candidate will be given a response.  Members in the group can send
376  * messages to the origin (one at a time).
377  *
378  * @param cfg configuration to use
379  * @param cls closure for the various callbacks that follow
380  * @param priv_key ECC key that will be used to sign messages for this
381  *                 multicast session; public key is used to identify the
382  *                 multicast group; FIXME: we'll likely want to use
383  *                 NOT the p521 curve here, but a cheaper one in the future
384  * @param join_policy what is the membership policy of the group?
385  * @param replay_cb function that can be called to replay a message
386  * @param test_cb function multicast can use to test group membership
387  * @param join_cb function called to approve / disapprove joining of a peer
388  * @param response_cb function called with messages from group members
389  * @return handle for the origin, NULL on error 
390  */
391 struct GNUNET_MULTICAST_Origin *
392 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 
393                                void *cls,
394                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
395                                enum GNUNET_MULTICAST_JoinPolicy join_policy,
396                                GNUNET_MULITCAST_ReplayCallback replay_cb,
397                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
398                                GNUNET_MULTICAST_MembershipChangeCallback join_cb,
399                                GNUNET_MULTICAST_ResponseCallback response_cb);
400
401
402 /**
403  * Handle for a request to send a message to all multicast group members
404  * (from the origin).
405  */
406 struct GNUNET_MULTICAST_MulticastRequest;
407
408
409 /**
410  * Send a message to the multicast group.
411  *
412  * @param origin handle to the multicast group
413  * @param size number of bytes to transmit
414  * @param cb function to call to get the message
415  * @param cb_cls closure for 'cb'
416  * @return NULL on error (i.e. request already pending)
417  */
418 struct GNUNET_MULTICAST_MulticastRequest *
419 GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
420                                 size_t size,
421                                 GNUNET_CONNECTION_TransmitReadyNotify cb,
422                                 void *cb_cls);
423
424
425 /**
426  * Cancel request for message transmission to multicast group.
427  *
428  * @param mr request to cancel
429  */
430 void
431 GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_MulticastRequest *mr);
432
433
434 /**
435  * End a multicast group.
436  *
437  * @param origin multicast group to terminate
438  */
439 void
440 GNUNET_MULTICAST_origin_end (struct GNUNET_MULTICAST_Origin *origin);
441
442
443 /**
444  * Join a multicast group.  The entity joining is always the local
445  * peer.  Further information about the candidate can be provided in
446  * the 'join_req' message.  If the join fails, the 'message_cb' is
447  * invoked with a (failure) response and then with 'NULL'.  If the
448  * join succeeds, outstanding (state) messages and ongoing multicast
449  * messages will be given to the 'message_cb' until the member decides
450  * to leave the group.  The 'test_cb' and 'replay_cb' functions may be
451  * called at anytime by the multicast service to support relaying
452  * messages to other members of the group.
453  *
454  * @param cfg configuration to use
455  * @param cls closure for callbacks
456  * @param pub_key ECC key that identifies the group
457  * @param max_known_message_id largest known message ID to the replay service;
458  *        all messages with IDs larger than this ID will be replayed if
459  *        possible (lower IDs will be considered known and thus only
460  *        be replayed upon explicit request)
461  * @param max_known_state_message_id largest known message ID with a non-zero
462  *                       value for the 'state_delta'; state messages with
463  *        larger IDs than this value will be replayed with high priority
464  *        (lower IDs will be considered known and thus only
465  *        be replayed upon explicit request)
466  * @param replay_cb function that can be called to replay messages
467  *        this peer already knows from this group; NULL if this
468  *        client is unable to support replay
469  * @param test_cb function multicast can use to test group membership
470  * @param message_cb function to be called for all messages we 
471  *        receive from the group, excluding those our replay_cb
472  *        already has
473  * @param join_req application-dependent join message to be passed to origin
474  *        (might, for example, contain a user 
475  *        bind user identity/pseudonym to peer identity, application-level
476  *        message to origin, etc.)
477  * @return handle for the member, NULL on error 
478  */
479 struct GNUNET_MULTICAST_Member *
480 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, 
481                               void *cls,
482                               const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
483                               uint64_t max_known_message_id,
484                               uint64_t max_known_state_message_id,
485                               GNUNET_MULTICAST_ReplayCallback replay_cb,
486                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
487                               GNUNET_MULTICAST_MulticastMessageCallback message_cb,
488                               const struct GNUNET_MessageHeader *join_req);
489
490
491 /**
492  * Handle for a replay request.
493  */
494 struct GNUNET_MULTICAST_ReplayRequest;
495
496
497 /**
498  * Request a message to be replayed.  Useful if messages below
499  * the 'max_known_*_id's given when joining are needed and not
500  * known to the client.
501  *
502  * @param member membership handle
503  * @param message_id ID of a message that this client would like to see replayed
504  * @param message_cb function to be called for the replayed message
505  * @param message_cb_cls closure for 'message_cb'
506  * @return replay request handle, NULL on error
507  */
508 struct GNUNET_MULTICAST_ReplayRequest *
509 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
510                                         uint64_t message_id,
511                                         GNUNET_MULTICAST_MulticastMessageCallback message_cb,
512                                         void *message_cb_cls);
513
514
515 /**
516  * Cancel a replay request.
517  *
518  * @param rr request to cancel
519  */
520 void
521 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_ReplayRequest *rr);
522
523
524 /**
525  * Leave a mutlicast group.
526  *
527  * @param member membership handle
528  */
529 void
530 GNUNET_MULTICAST_member_leave (struct GNUNET_MULTICAST_Member *member);
531
532
533 /**
534  * Handle for a message to be delivered to the origin.
535  */
536 struct GNUNET_MULTICAST_ResponseRequest;
537
538
539 /**
540  * Send a message to the origin of the multicast group.  
541  * 
542  * @param member membership handle
543  * @param size number of bytes we want to send to origin
544  * @param cb callback to call to get the message
545  * @param cb_cls closure for 'cb'
546  * @return handle to cancel request, NULL on error (i.e. request already pending)
547  */
548 struct GNUNET_MULTICAST_ResponseRequest *
549 GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
550                                    size_t size,
551                                    GNUNET_CONNECTION_TransmitReadyNotify cb,
552                                    void *cb_cls);
553
554
555 /**
556  * Cancel request for message transmission to origin.
557  *
558  * @param rr request to cancel
559  */
560 void
561 GNUNET_MULTICAST_member_to_origin_cancel (struct GNUNET_MULTICAST_ResponseRequest *rr);
562
563
564
565 #if 0                           /* keep Emacsens' auto-indent happy */
566 {
567 #endif
568 #ifdef __cplusplus
569 }
570 #endif
571
572 /* ifndef GNUNET_MULTICAST_SERVICE_H */
573 #endif
574 /* end of gnunet_multicast_service.h */