-cleaning
[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  * TODO:
27  * - need to support async message transmission, etc.
28  * - need to do sanity check that this is consistent
29  *   with current ideas for the PSYC layer's needs
30  */
31
32 #ifndef GNUNET_MULTICAST_SERVICE_H
33 #define GNUNET_MULTICAST_SERVICE_H
34
35 #ifdef __cplusplus
36 extern "C"
37 {
38 #if 0                           /* keep Emacsens' auto-indent happy */
39 }
40 #endif
41 #endif
42
43 #include "gnunet_util_lib.h"
44 #include "gnunet_transport_service.h"
45
46 /**
47  * Version number of GNUnet-multicast API.
48  */
49 #define GNUNET_MULTICAST_VERSION 0x00000000
50
51
52 /**
53  * Opaque handle for a multicast group member.
54  */
55 struct GNUNET_MULTICAST_Member;
56
57 /**
58  * Handle for the origin of a multicast group.
59  */
60 struct GNUNET_MULTICAST_Origin;
61
62 /**
63  * Group membership policies.
64  */
65 enum GNUNET_MULTICAST_JoinPolicy
66 {
67   /**
68    * Anyone can join the group, without announcing his presence; all
69    * messages are always public and can be distributed freely.  Joins
70    * may be announced, but this is not required.
71    */
72   GNUNET_MULTICAST_JP_ANONYMOUS = 0,
73
74   /**
75    * Origin must approve membership to the group, messages must only be
76    * distributed to current group members.  This includes the group
77    * state as well as transient messages.
78    */
79   GNUNET_MULTICAST_JP_PRIVATE = 1
80
81 #if IDEAS_FOR_FUTURE
82   /**
83    * Anyone can freely join the group (no approval required); however,
84    * transient messages must only be distributed to current group
85    * members, so the origin must still acknowledge that the member
86    * joined before transient messages are delivered.  As approval is
87    * guaranteed, the presistent group state can de synchronized freely
88    * immediately, prior to origin confirmation
89    */
90   GNUNET_MULTICAST_JP_OPEN = 2
91 #endif
92
93 };
94
95
96 /**
97  * Opaque handle to a replay request from the multicast service.
98  */
99 struct GNUNET_MULTICAST_ReplayHandle;
100
101
102 /**
103  * Functions with this signature are called whenever the multicast
104  * service needs a message to be replayed.  Implementations of this
105  * function MUST call 'GNUNET_MULTICAST_replay' ONCE (with a message
106  * or an error); however, if the origin is destroyed or the group is
107  * left, the replay handle must no longer be used.
108  *
109  * @param cls closure (set from GNUNET_MULTICAST_origin_start/join)
110  * @param message_id which message should be replayed
111  * @param rh handle to pass to message transmit function
112  */
113 typedef void (*GNUNET_MULTICAST_ReplayCallback) (void *cls,
114                                                  uint64_t message_id,
115                                                  struct GNUNET_MULTICAST_ReplayHandle *rh);
116
117
118 /**
119  * Possible error codes during replay.
120  */
121 enum GNUNET_MULTICAST_ReplayErrorCode
122 {
123   
124   /**
125    * Everything is fine.
126    */ 
127   GNUNET_MULTICAST_REC_OK = 0,
128
129   /**
130    * Message has been discarded (likely transient message that was too old).
131    */ 
132   GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1,
133
134   /**
135    * Message ID counter was larger than the highest counter this
136    * replay function has ever encountered; thus it is likely the
137    * origin never sent it and we're at the HEAD of the multicast
138    * stream as far as this node is concerned.
139    */ 
140   GNUNET_MULTICAST_REC_PAST_HEAD = 2,
141
142   /**
143    * Internal error (i.e. database error).  Try some other peer.
144    */ 
145   GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3
146
147 };
148
149
150 /**
151  * Header of a multicast message.  This format is public as the replay
152  * mechanism must replay messages using the same format.
153  */
154 struct GNUNET_MULTICAST_MessageHeader
155 {
156
157   /**
158    * Header for all multicast messages from the origin.
159    */
160   struct GNUNET_MessageHeader header;
161
162   /**
163    * How many hops has this message taken since the origin?
164    * (helpful to determine shortest paths to the origin for responses
165    *  among honest peers; updated at each hop and thus not signed
166    *  and not secure)
167    */
168   uint32_t hop_counter;
169
170   /**
171    * ECC signature of the message.
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;
184
185   /**
186    * Counter that monotonically increases whenever a member
187    * leaves the group.
188    */
189   uint64_t group_generation;
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;
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
224 /**
225  * Replay a message from the multicast group.
226  *
227  * @param rh replay handle identifying which replay operation was requested
228  * @param msg replayed message, NULL if unknown/error
229  * @param ec error code
230  */
231 void
232 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
233                          const struct GNUNET_MULTICAST_MessageHeader *msg,
234                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
235
236
237 /**
238  * Method called whenever another peer wants to join or has left a 
239  * multicast group.
240  *
241  * @param cls closure
242  * @param peer identity of the peer that wants to join or leave
243  * @param join_req application-dependent join message from the new user
244  *        (might, for example, contain a user 
245  *        bind user identity/pseudonym to peer identity, application-level
246  *        message to origin, etc.)
247  * @param is_joining GNUNET_YES if the peer wants to join, GNUNET_NO if the peer left
248  * @return GNUNET_OK if joining is approved, GNUNET_SYSERR if it is disapproved;
249  *         GNUNET_NO should be returned for peers leaving 
250  */
251 typedef int (*GNUNET_MULTICAST_MembershipChangeCallback)(void *cls,
252                                                          const struct GNUNET_PeerIdentity *peer,
253                                                          const struct GNUNET_MessageHeader *join_req,
254                                                          int is_joining);
255
256
257 /**
258  * Method called to test if a member was in the group at a particular time.
259  *
260  * @param cls closure
261  * @param peer identity of the peer that we want to test
262  * @param message_id message ID for which we want to do the test
263  * @param group_generation the generation of the group for which we want to do the test
264  * @return GNUNET_YES if peer was a member, GNUNET_NO if peer was not a member,
265  *         GNUNET_SYSERR if we cannot answer the membership test
266  */
267 typedef int (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
268                                                        const struct GNUNET_PeerIdentity *peer,
269                                                        uint64_t message_id,
270                                                        uint64_t group_generation);
271
272
273 /**
274  * Function called whenever a group member has transmitted a message
275  * to the origin (other than joining or leaving).
276  *
277  * @param cls closure (set from GNUNET_MULTICAST_origin_start)
278  * @param sender identity of the sender
279  * @param response_id unique counter for the response from this sender to this origin
280  * @param msg message to the origin
281  */
282 typedef void (*GNUNET_MULTICAST_ResponseCallback) (void *cls,
283                                                    const struct GNUNET_PeerIdentity *sender,
284                                                    uint64_t response_id,
285                                                    const struct GNUNET_MessageHeader *msg);
286
287
288 /**
289  * Function called whenever a group member is receiving a message from
290  * the origin.
291  *
292  * @param cls closure (set from GNUNET_MULTICAST_member_join)
293  * @param msg message from the origin, NULL if the origin shut down
294  *        (or we were kicked out, and we should thus call GNUNET_MULTICAST_member_leave next)
295  */
296 typedef void (*GNUNET_MULTICAST_MessageCallback) (void *cls,
297                                                   const struct GNUNET_MULTICAST_MessageHeader *msg);
298
299
300 /**
301  * Start a multicast group.
302  *
303  * @param cfg configuration to use
304  * @param cls closure for the various callbacks that follow
305  * @param priv_key ECC key that will be used to sign messages for this
306  *                 multicast session; public key is used to identify the
307  *                 multicast group; FIXME: we'll likely want to use
308  *                 NOT the p521 curve here, but a cheaper one in the future
309  * @param join_policy what is the membership policy of the group?
310  * @param replay_cb function that can be called to replay a message
311  * @param test_cb function multicast can use to test group membership
312  * @param join_cb function called to approve / disapprove joining of a peer
313  * @param response_cb function called with messages from group members
314  * @return handle for the origin, NULL on error 
315  */
316 struct GNUNET_MULTICAST_Origin *
317 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 
318                                void *cls,
319                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
320                                enum GNUNET_MULTICAST_JoinPolicy join_policy,
321                                GNUNET_MULITCAST_ReplayCallback replay_cb,
322                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
323                                GNUNET_MULTICAST_MembershipChangeCallback join_cb,
324                                GNUNET_MULTICAST_ResponseCallback response_cb);
325
326
327 /**
328  * Send a message to the multicast group.
329  *
330  * @param origin handle to the multicast group
331  * @param msg_body body of the message to transmit
332  * FIXME: change to notify_transmit_ready-style to wait for ACKs?
333  */
334 void
335 GNUNET_MULTICAST_origin_send_to_all (struct GNUNET_MULTICAST_Origin *origin,
336                                      const struct GNUNET_MessageHeader *msg_body);
337
338
339 /**
340  * End a multicast group.
341  *
342  * @param origin multicast group to terminate
343  */
344 void
345 GNUNET_MULTICAST_origin_end (struct GNUNET_MULTICAST_Origin *origin);
346
347
348 /**
349  * Join a multicast group.  The entity joining is always the local peer.
350  *
351  * @param cfg configuration to use
352  * @param cls closure for callbacks
353  * @param pub_key ECC key that identifies the group
354  * @param max_known_message_id largest known message ID to the replay service;
355  *        all messages with IDs larger than this ID will be replayed if
356  *        possible (lower IDs will be considered known and thus only
357  *        be replayed upon explicit request)
358  * @param max_known_state_message_id largest known message ID with a non-zero
359  *                       value for the 'state_delta'; state messages with
360  *        larger IDs than this value will be replayed with high priority
361  *        (lower IDs will be considered known and thus only
362  *        be replayed upon explicit request)
363  * @param replay_cb function that can be called to replay messages
364  *        this peer already knows from this group; NULL if this
365  *        client is unable to support replay
366  * @param test_cb function multicast can use to test group membership
367  * @param message_cb function to be called for all messages we 
368  *        receive from the group, excluding those our replay_cb
369  *        already has
370  * @param join_req application-dependent join message to be passed to origin
371  *        (might, for example, contain a user 
372  *        bind user identity/pseudonym to peer identity, application-level
373  *        message to origin, etc.)
374  * @return handle for the member, NULL on error 
375  */
376 struct GNUNET_MULTICAST_Member *
377 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, 
378                               void *cls,
379                               const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
380                               uint64_t max_known_message_id,
381                               uint64_t max_known_state_message_id,
382                               GNUNET_MULTICAST_ReplayCallback replay_cb,
383                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
384                               GNUNET_MULTICAST_MessageCallback message_cb,
385                               const struct GNUNET_MessageHeader *join_req);
386
387
388 /**
389  * Handle for a replay request.
390  */
391 struct GNUNET_MULTICAST_ReplayRequest;
392
393
394 /**
395  * Request a message to be replayed.  Useful if messages below
396  * the 'max_known_*_id's given when joining are needed and not
397  * known to the client.
398  *
399  * FIXME: we currently use the 'replay_cb' from the member_join call;
400  * we might alternatively add a different cb here.
401  *
402  * @param member membership handle
403  * @param message_id ID of a message that this client would like to see replayed
404  * @return replay request handle, NULL on error
405  */
406 struct GNUNET_MULTICAST_ReplayRequest *
407 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
408                                         uint64_t message_id);
409
410
411 /**
412  * Cancel a replay request.
413  *
414  * @param rr request to cancel
415  */
416 void
417 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_ReplayRequest *rr);
418
419
420 /**
421  * Leave a mutlicast group.
422  *
423  * @param member membership handle
424  */
425 void
426 GNUNET_MULTICAST_member_leave (struct GNUNET_MULTICAST_Member *member);
427
428
429 /**
430  * Handle for a message to be delivered to the origin.
431  */
432 struct GNUNET_MULTICAST_ResponseRequest;
433
434
435 /**
436  * Send a message to the origin of the multicast group.  FIXME: how
437  * will we do routing/flow-control of responses?
438  * 
439  * @param member membership handle
440  * @param msg message to send to the origin
441  * FIXME: change to notify_transmit_ready-style to wait for ACKs...
442  */
443 void
444 GNUNET_MULTICAST_member_message_to_origin (struct GNUNET_MULTICAST_Member *member,
445                                            const struct GNUNET_MessageHeader *msg);
446
447
448
449 #if 0                           /* keep Emacsens' auto-indent happy */
450 {
451 #endif
452 #ifdef __cplusplus
453 }
454 #endif
455
456 /* ifndef GNUNET_MULTICAST_SERVICE_H */
457 #endif
458 /* end of gnunet_multicast_service.h */