-update
[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 /**
146  * Header of a multicast message.  This format is public as the replay
147  * mechanism must replay messages using the same format.
148  */
149 struct GNUNET_MULTICAST_MessageHeader
150 {
151
152   /**
153    * Header for all multicast messages from the origin.
154    */
155   struct GNUNET_MessageHeader header;
156
157   /**
158    * How many hops has this message taken since the origin?
159    * (helpful to determine shortest paths to the origin for responses
160    *  among honest peers; updated at each hop and thus not signed
161    *  and not secure)
162    */
163   uint32_t hop_counter;
164
165   /**
166    * ECC signature of the message.
167    */
168   struct GNUNET_CRYPTO_EccSignature signature;
169
170   /**
171    * Signature of the multicast message.
172    */
173   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
174
175   /**
176    * Number of the message, monotonically increasing.
177    */
178   uint64_t message_id;
179
180   /**
181    * Counter that monotonically increases whenever a member
182    * leaves the group.
183    */
184   uint64_t group_generation;
185
186   /**
187    * Difference between the current message_id and the message_id of
188    * the preceeding non-transient message.  Zero for transient
189    * messages, UINT64_MAX for the first message, or any other message
190    * creating a full state reset by the origin.  By subtracting
191    * 'state_delta' from 'message_id', it is possible to calculate the
192    * message ID of the preceeding non-transient message and thus
193    * quickly traverse all state changes up to the last full state
194    * reset by the origin.  This is useful as it allows joining clients
195    * to quickly reassemble the state while skipping over transient
196    * messages (and doing so without having to trust intermediaries to
197    * do it right, as the indices in the chain are signed).  If the
198    * state chain is getting too long, the origin can choose to
199    * originate a state message with a state_delta of UINT64_MAX,
200    * thereby starting a new chain.  The origin will then have to
201    * re-create the full state with state update messages following the
202    * state reset message.
203    */
204   uint64_t state_delta;
205
206   /**
207    * Header for the message body.  Three message types are
208    * specifically understood by multicast, namely "peer join", "peer
209    * leave", and "group terminated".  Multicast will use those
210    * messages to update its list of candidates for content
211    * distribution.  All other message types are application-specific.
212    */
213   struct GNUNET_MessageHeader body;
214
215   /* followed by message body */
216 };
217
218
219 /**
220  * Replay a message from the multicast group.
221  *
222  * @param rh replay handle identifying which replay operation was requested
223  * @param msg replayed message, NULL if unknown/error
224  * @param ec error code
225  */
226 void
227 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
228                          const struct GNUNET_MULTICAST_MessageHeader *msg,
229                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
230
231
232 /**
233  * Method called whenever another peer wants to join or has left a 
234  * multicast group.
235  *
236  * @param cls closure
237  * @param peer identity of the peer that wants to join or leave
238  * @param join_req application-dependent join message from the new user
239  *        (might, for example, contain a user 
240  *        bind user identity/pseudonym to peer identity, application-level
241  *        message to origin, etc.)
242  * @param is_joining GNUNET_YES if the peer wants to join, GNUNET_NO if the peer left
243  * @return GNUNET_OK if joining is approved, GNUNET_SYSERR if it is disapproved;
244  *         GNUNET_NO should be returned for peers leaving 
245  */
246 typedef int (*GNUNET_MULTICAST_MembershipChangeCallback)(void *cls,
247                                                          const struct GNUNET_PeerIdentity *peer,
248                                                          const struct GNUNET_MessageHeader *join_req,
249                                                          int is_joining);
250
251
252 /**
253  * Method called to test if a member was in the group at a particular time.
254  *
255  * @param cls closure
256  * @param peer identity of the peer that we want to test
257  * @param message_id message ID for which we want to do the test
258  * @param group_generation the generation of the group for which we want to do the test
259  * @return GNUNET_YES if peer was a member, GNUNET_NO if peer was not a member,
260  *         GNUNET_SYSERR if we cannot answer the membership test
261  */
262 typedef int (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
263                                                        const struct GNUNET_PeerIdentity *peer,
264                                                        uint64_t message_id,
265                                                        uint64_t group_generation);
266
267
268 /**
269  * Function called whenever a group member has transmitted a message
270  * to the origin (other than joining or leaving).
271  *
272  * @param cls closure (set from GNUNET_MULTICAST_origin_start)
273  * @param sender identity of the sender
274  * @param response_id unique counter for the response from this sender to this origin
275  * @param msg message to the origin
276  */
277 typedef void (*GNUNET_MULTICAST_ResponseCallback) (void *cls,
278                                                    const struct GNUNET_PeerIdentity *sender,
279                                                    uint64_t response_id,
280                                                    const struct GNUNET_MessageHeader *msg);
281
282
283 /**
284  * Function called whenever a group member is receiving a message from
285  * the origin.
286  *
287  * @param cls closure (set from GNUNET_MULTICAST_member_join)
288  * @param msg message from the origin, NULL if the origin shut down
289  *        (or we were kicked out, and we should thus call GNUNET_MULTICAST_member_leave next)
290  */
291 typedef void (*GNUNET_MULTICAST_MessageCallback) (void *cls,
292                                                   const struct GNUNET_MULTICAST_MessageHeader *msg);
293
294
295 /**
296  * Start a multicast group.
297  *
298  * @param cfg configuration to use
299  * @param cls closure for the various callbacks that follow
300  * @param priv_key ECC key that will be used to sign messages for this
301  *                 multicast session; public key is used to identify the
302  *                 multicast group; FIXME: we'll likely want to use
303  *                 NOT the p521 curve here, but a cheaper one in the future
304  * @param join_policy what is the membership policy of the group?
305  * @param replay_cb function that can be called to replay a message
306  * @param test_cb function multicast can use to test group membership
307  * @param join_cb function called to approve / disapprove joining of a peer
308  * @param response_cb function called with messages from group members
309  * @return handle for the origin, NULL on error 
310  */
311 struct GNUNET_MULTICAST_Origin *
312 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 
313                                void *cls,
314                                struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
315                                enum GNUNET_MULTICAST_JoinPolicy join_policy,
316                                GNUNET_MULITCAST_ReplayCallback replay_cb,
317                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
318                                GNUNET_MULTICAST_MembershipChangeCallback join_cb,
319                                GNUNET_MULTICAST_ResponseCallback response_cb);
320
321
322 /**
323  * Send a message to the multicast group.
324  *
325  * @param origin handle to the multicast group
326  * @param msg_body body of the message to transmit
327  */
328 void
329 GNUNET_MULTICAST_origin_send_to_all (struct GNUNET_MULTICAST_Origin *origin,
330                                      const struct GNUNET_MessageHeader *msg_body);
331
332
333 /**
334  * End a multicast group.
335  *
336  * @param origin multicast group to terminate
337  */
338 void
339 GNUNET_MULTICAST_origin_end (struct GNUNET_MULTICAST_Origin *origin);
340
341
342 /**
343  * Join a multicast group.  The entity joining is always the local peer.
344  *
345  * @param cfg configuration to use
346  * @param cls closure for callbacks
347  * @param pub_key ECC key that identifies the group
348  * @param max_known_message_id largest known message ID to the replay service;
349  *        all messages with IDs larger than this ID will be replayed if
350  *        possible (lower IDs will be considered known and thus only
351  *        be replayed upon explicit request)
352  * @param max_known_state_message_id largest known message ID with a non-zero
353  *                       value for the 'state_delta'; state messages with
354  *        larger IDs than this value will be replayed with high priority
355  *        (lower IDs will be considered known and thus only
356  *        be replayed upon explicit request)
357  * @param replay_cb function that can be called to replay messages
358  *        this peer already knows from this group; NULL if this
359  *        client is unable to support replay
360  * @param test_cb function multicast can use to test group membership
361  * @param message_cb function to be called for all messages we 
362  *        receive from the group, excluding those our replay_cb
363  *        already has
364  * @param join_req application-dependent join message to be passed to origin
365  *        (might, for example, contain a user 
366  *        bind user identity/pseudonym to peer identity, application-level
367  *        message to origin, etc.)
368  * @return handle for the member, NULL on error 
369  */
370 struct GNUNET_MULTICAST_Member *
371 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, 
372                               void *cls,
373                               struct GNUNET_CRYPTO_EccPublicKey *pub_key,
374                               uint64_t max_known_message_id,
375                               uint64_t max_known_state_message_id,
376                               GNUNET_MULTICAST_ReplayCallback replay_cb,
377                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
378                               GNUNET_MULTICAST_MessageCallback message_cb,
379                               const struct GNUNET_MessageHeader *join_req);
380
381
382 /**
383  * Handle for a replay request.
384  */
385 struct GNUNET_MULTICAST_ReplayRequest;
386
387
388 /**
389  * Request a message to be replayed.  Useful if messages below
390  * the 'max_known_*_id's given when joining are needed and not
391  * known to the client.
392  *
393  * FIXME: we currently use the 'replay_cb' from the member_join call;
394  * we might alternatively add a different cb here.
395  *
396  * @param member membership handle
397  * @param message_id ID of a message that this client would like to see replayed
398  * @return replay request handle, NULL on error
399  */
400 struct GNUNET_MULTICAST_ReplayRequest *
401 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
402                                         uint64_t message_id);
403
404
405 /**
406  * Cancel a replay request.
407  *
408  * @param rr request to cancel
409  */
410 void
411 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_ReplayRequest *rr);
412
413
414 /**
415  * Leave a mutlicast group.
416  *
417  * @param member membership handle
418  */
419 void
420 GNUNET_MULTICAST_member_leave (struct GNUNET_MULTICAST_Member *member);
421
422
423 /**
424  * Handle for a message to be delivered to the origin.
425  */
426 struct GNUNET_MULTICAST_ResponseRequest;
427
428
429 /**
430  * Send a message to the origin of the multicast group.  FIXME: how
431  * will we do routing/flow-control of responses?
432  * 
433  * @param member membership handle
434  * @param msg message to send to the origin
435  * FIXME: change to notify_transmit_ready-style to wait for ACKs...
436  */
437 void
438 GNUNET_MULTICAST_member_respond_to_origin (struct GNUNET_MULTICAST_Member *member,
439                                            const struct GNUNET_MessageHeader *msg);
440
441
442
443 #if 0                           /* keep Emacsens' auto-indent happy */
444 {
445 #endif
446 #ifdef __cplusplus
447 }
448 #endif
449
450 /* ifndef GNUNET_MULTICAST_SERVICE_H */
451 #endif
452 /* end of gnunet_multicast_service.h */