23d871a39196c4e6923670b2917a6a64aecd1c84
[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  * @author Gabor X Toth
26  */
27
28 #ifndef GNUNET_MULTICAST_SERVICE_H
29 #define GNUNET_MULTICAST_SERVICE_H
30
31 #ifdef __cplusplus
32 extern "C"
33 {
34 #if 0                           /* keep Emacsens' auto-indent happy */
35 }
36 #endif
37 #endif
38
39 #include "gnunet_util_lib.h"
40 #include "gnunet_transport_service.h"
41
42 /** 
43  * Version number of GNUnet-multicast API.
44  */
45 #define GNUNET_MULTICAST_VERSION 0x00000000
46
47
48 /** 
49  * Opaque handle for a multicast group member.
50  */
51 struct GNUNET_MULTICAST_Member;
52
53 /** 
54  * Handle for the origin of a multicast group.
55  */
56 struct GNUNET_MULTICAST_Origin;
57
58 /** 
59  * Policy flags for the group.
60  */
61 enum GNUNET_MULTICAST_GroupFlags
62 {
63   /**
64    * Admission must be confirmed by the origin.
65    */
66   GNUNET_MULTICAST_GROUP_ADMISSION_CONTROL = 1 << 0,
67
68   /**
69    * Past messages are only available to peers who were a member at the time
70    * they were sent to the group.
71    */
72   GNUNET_MULTICAST_GROUP_RESTRICTED_HISTORY = 1 << 1,
73 };
74
75 /** 
76  * Group membership policies.
77  */
78 enum GNUNET_MULTICAST_GroupPolicy
79 {
80   /**
81    * Anyone can join the group, without announcing his presence;
82    * all messages are always public and can be distributed freely.
83    * Joins may be announced, but this is not required.
84    */
85   GNUNET_MULTICAST_GROUP_ANONYMOUS = 0,
86
87   /** 
88    * Origin must approve membership to the group, messages must only be
89    * distributed to current group members.  This includes the group
90    * state as well as transient messages.
91    */
92   GNUNET_MULTICAST_GROUP_PRIVATE
93     = GNUNET_MULTICAST_GROUP_ADMISSION_CONTROL
94     | GNUNET_MULTICAST_GROUP_RESTRICTED_HISTORY,
95
96 #if IDEAS_FOR_FUTURE
97   /** 
98    * Anyone can freely join the group (no approval required);
99    * however, messages must only be distributed to current group
100    * members, so the origin must still acknowledge that the member
101    * joined before transient messages are delivered.  As approval is
102    * guaranteed, the presistent group state can be synchronized freely
103    * immediately, prior to origin confirmation.
104    */
105   GNUNET_MULTICAST_GROUP_OPEN
106     = GNUNET_MULTICAST_GROUP_RESTRICTED_HISTORY,
107
108   /**
109    * Origin must approve membership to the group, but past messages can be
110    * freely distributed to members.
111    */
112   GNUNET_MULTICAST_GROUP_CLOSED
113     = GNUNET_MULTICAST_GROUP_ADMISSION_CONTROL,
114 ,
115 #endif
116
117 };
118
119 enum GNUNET_MULTICAST_MessageFlags
120 {
121   /**
122    * First fragment of a message.
123    */
124   GNUNET_MULTICAST_MESSAGE_FIRST_FRAGMENT = 1 << 0,
125
126   /**
127    * Last fragment of a message.
128    */
129   GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT = 1 << 1,
130
131   /** 
132    * OR'ed flags if message is not fragmented.
133    */
134   GNUNET_MULTICAST_MESSAGE_NOT_FRAGMENTED
135     = GNUNET_MULTICAST_MESSAGE_FIRST_FRAGMENT
136     | GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT
137 };
138
139
140 GNUNET_NETWORK_STRUCT_BEGIN
141
142 /** 
143  * Header of a multicast message fragment.
144  *
145  * This format is public as the replay mechanism must replay message fragments using the
146  * same format.  This is needed as we want to integrity-check message fragments within
147  * the multicast layer to avoid multicasting mal-formed messages.
148  */
149 struct GNUNET_MULTICAST_MessageHeader
150 {
151
152   /** 
153    * Header for all multicast message fragments from the origin.
154    */
155   struct GNUNET_MessageHeader header;
156
157   /** 
158    * Number of hops this message fragment has taken since the origin.
159    *
160    * Helpful to determine shortest paths to the origin among honest peers for
161    * unicast requests from members.  Updated at each hop and thus not signed and
162    * not secure.
163    */
164   uint32_t hop_counter GNUNET_PACKED;
165
166   /** 
167    * ECC signature of the message fragment.
168    *
169    * Signature must match the public key of the multicast group.
170    */
171   struct GNUNET_CRYPTO_EccSignature signature;
172
173   /** 
174    * Purpose for the signature and size of the signed data.
175    */
176   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
177
178   /** 
179    * Number of the message fragment, monotonically increasing.
180    */
181   uint64_t fragment_id GNUNET_PACKED;
182
183   /** 
184    * Number of fragments before the current one that has the same @a message_id.
185    *
186    * 0 for the first fragment of a message.
187    * This allows replaying a message with all of its fragments.
188    */
189   uint64_t fragment_delta GNUNET_PACKED;
190
191   /** 
192    * Byte offset of this @e fragment of the @e message.
193    */
194   uint64_t fragment_offset GNUNET_PACKED;
195
196   /** 
197    * Number of the message this fragment belongs to.
198    *
199    * Set in GNUNET_MULTICAST_origin_to_all().
200    */
201   uint64_t message_id GNUNET_PACKED;
202
203   /** 
204    * Counter that monotonically increases whenever a member parts the group.
205    *
206    * Set in GNUNET_MULTICAST_origin_to_all().
207    *
208    * It has significance in case of replay requests: when a member has missed
209    * messages and gets a replay request: in this case if the @a group_generation
210    * is still the same before and after the missed messages, it means that no
211    * @e join or @e part operations happened during the missed messages.
212    */
213   uint64_t group_generation GNUNET_PACKED;
214
215   /**
216    * Flags for this message fragment.
217    */
218   enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
219
220   /* Followed by message body. */
221 };
222
223 GNUNET_NETWORK_STRUCT_END
224
225 GNUNET_NETWORK_STRUCT_BEGIN
226
227 /** 
228  * Header of a request from a member to the origin.
229  *
230  * FIXME: this struct is going to be internal.
231  */
232 struct GNUNET_MULTICAST_RequestHeader
233 {
234   /** 
235    * Header for all requests from a member to the origin.
236    */
237   struct GNUNET_MessageHeader header;
238
239   /**
240    * Public key of the sending member.
241    */
242   struct GNUNET_CRYPTO_EccPublicKey member_key;
243
244   /** 
245    * ECC signature of the request fragment.
246    *
247    * Signature must match the public key of the multicast group.
248    */
249   struct GNUNET_CRYPTO_EccSignature signature;
250
251   /** 
252    * Purpose for the signature and size of the signed data.
253    */
254   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
255
256   /** 
257    * Number of the request fragment, monotonically increasing.
258    */
259   uint64_t fragment_id GNUNET_PACKED;
260
261   /** 
262    * Byte offset of this @e fragment of the @e request.
263    */
264   uint64_t fragment_offset GNUNET_PACKED;
265
266   /** 
267    * Number of the request this fragment belongs to.
268    *
269    * Set in GNUNET_MULTICAST_origin_to_all().
270    */
271   uint64_t request_id GNUNET_PACKED;
272
273   /**
274    * Flags for this request.
275    */
276   enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
277
278   /* Followed by request body. */
279 };
280
281 GNUNET_NETWORK_STRUCT_END
282
283
284 GNUNET_NETWORK_STRUCT_BEGIN
285
286 /** 
287  * Header of a join request sent to the origin or another member.
288  *
289  * FIXME: this struct is going to be internal.
290  */
291 struct GNUNET_MULTICAST_JoinRequest {
292   /** 
293    * Header for the join request.
294    */
295   struct GNUNET_MessageHeader header;
296
297   /** 
298    * ECC signature of the rest of the fields of the join request.
299    *
300    * Signature must match the public key of the joining member.
301    */
302   struct GNUNET_CRYPTO_EccSignature signature;
303
304   /** 
305    * Purpose for the signature and size of the signed data.
306    */
307   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
308
309   /**
310    * Public key of the target group.
311    */
312   struct GNUNET_CRYPTO_EccPublicKey group_key;
313
314   /**
315    * Public key of the joining member.
316    */
317   struct GNUNET_CRYPTO_EccPublicKey member_key;
318
319   /**
320    * Peer identity of the joining member.
321    */
322   struct GNUNET_PeerIdentity member_peer;
323
324   /* Followed by request body. */
325 };
326
327 GNUNET_NETWORK_STRUCT_END
328
329
330 /** 
331  * Handle that identifies a join request.
332  *
333  * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the
334  * corresponding calls to GNUNET_MULTICAST_join_decision().
335  */
336 struct GNUNET_MULTICAST_JoinHandle;
337
338
339 /** 
340  * Function to call with the decision made for a join request.
341  *
342  * Must be called once and only once in response to an invocation of the
343  * #GNUNET_MULTICAST_JoinCallback.
344  *
345  * @param jh Join request handle.
346  * @param is_admitted #GNUNET_YES if joining is approved,
347  *        #GNUNET_NO if it is disapproved
348  * @param relay_count Number of relays given.
349  * @param relays Array of suggested peers that might be useful relays to use
350  *        when joining the multicast group (essentially a list of peers that
351  *        are already part of the multicast group and might thus be willing
352  *        to help with routing).  If empty, only this local peer (which must
353  *        be the multicast origin) is a good candidate for building the
354  *        multicast tree.  Note that it is unnecessary to specify our own
355  *        peer identity in this array.
356  * @param join_response Message to send in response to the joining peer;
357  *        can also be used to redirect the peer to a different group at the
358  *        application layer; this response is to be transmitted to the
359  *        peer that issued the request even if admission is denied.
360  */
361 void
362 GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
363                                 int is_admitted,
364                                 unsigned int relay_count,
365                                 const struct GNUNET_PeerIdentity *relays,
366                                 const struct GNUNET_MessageHeader *join_response);
367
368
369 /** 
370  * Method called whenever another peer wants to join the multicast group.
371  *
372  * Implementations of this function must call GNUNET_MULTICAST_join_decision()
373  * with the decision.
374  *
375  * @param cls Closure.
376  * @param peer Identity of the member that wants to join.
377  * @param join_req Application-dependent join message from the new member
378  *        (might, for example, contain a user,
379  *        bind user identity/pseudonym to peer identity, application-level
380  *        message to origin, etc.).
381  * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison().
382  */
383 typedef void
384 (*GNUNET_MULTICAST_JoinCallback) (void *cls,
385                                   const struct GNUNET_EccPublicKey *member_key,
386                                   const struct GNUNET_MessageHeader *join_req,
387                                   struct GNUNET_MULTICAST_JoinHandle *jh);
388
389
390 /** 
391  * Handle to pass back for the answer of a membership test.
392  */
393 struct GNUNET_MULTICAST_MembershipTestHandle;
394
395
396 /** 
397  * Call informing multicast about the decision taken for a membership test.
398  *
399  * @param mth Handle that was given for the query.
400  * @param result #GNUNET_YES if peer was a member, #GNUNET_NO if peer was not a member,
401  *        #GNUNET_SYSERR if we cannot answer the membership test.
402  */
403 void
404 GNUNET_MULTICAST_membership_test_result (struct GNUNET_MULTICAST_MembershipTestHandle *mth,
405                                          int result);
406
407
408 /** 
409  * Method called to test if a member was in the group at a particular time.
410  *
411  * It is called when a replay request is received to determine if the requested
412  * message can be replayed.
413  *
414  * @param cls Closure.
415  * @param member_key Identity of the member that we want to test.
416  * @param message_id Message ID for which to perform the test.
417  * @param group_generation Group generation of the message. It has relevance if
418  *        the message consists of multiple fragments with different group
419  *        generations.
420  * @param mth Handle to give to GNUNET_MULTICAST_membership_test_answer().
421  */
422 typedef void
423 (*GNUNET_MULTICAST_MembershipTestCallback) (void *cls,
424                                             const struct GNUNET_CRYPTO_EccPublicKey *member_key,
425                                             uint64_t message_id,
426                                             uint64_t group_generation,
427                                             struct GNUNET_MULTICAST_MembershipTestHandle *mth);
428
429
430 /** 
431  * Function called whenever a group member has transmitted a request
432  * to the origin (other than joining or leaving).
433  *
434  * @param cls Closure (set from GNUNET_MULTICAST_origin_start).
435  * @param sender Identity of the sender.
436  * @param req Request to the origin.
437  * @param flags Flags for the request.
438  */
439 typedef void
440 (*GNUNET_MULTICAST_RequestCallback) (void *cls,
441                                      const struct GNUNET_EccPublicKey *member_key,
442                                      const struct GNUNET_MessageHeader *req,
443                                      enum GNUNET_MULTICAST_MessageFlags flags);
444
445
446 /** 
447  * Function called whenever a group member is receiving a message fragment from
448  * the origin.
449  *
450  * If admission to the group is denied, this function is called once with the
451  * response of the @e origin (as given to GNUNET_MULTICAST_join_decision()) and
452  * then a second time with NULL to indicate that the connection failed for good.
453  *
454  * @param cls Closure (set from GNUNET_MULTICAST_member_join())
455  * @param msg Message from the origin, NULL if the origin shut down
456  *        (or we were kicked out, and we should thus call
457  *        GNUNET_MULTICAST_member_part() next)
458  */
459 typedef void
460 (*GNUNET_MULTICAST_MessageCallback) (void *cls,
461                                      const struct GNUNET_MULTICAST_MessageHeader *msg);
462
463
464 /** 
465  * Opaque handle to a replay request from the multicast service.
466  */
467 struct GNUNET_MULTICAST_ReplayHandle;
468
469
470 /** 
471  * Functions with this signature are called whenever the multicast service needs
472  * a message to be replayed.
473  *
474  * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
475  * (with a message or an error); however, if the origin is destroyed or the
476  * group is left, the replay handle must no longer be used.
477  *
478  * @param cls Closure (set from GNUNET_MULTICAST_origin_start()
479  *        or GNUNET_MULTICAST_member_join()).
480  * @param fragment_id Which message fragment should be replayed.
481  * @param message_id Which message should be replayed.
482  * @param flags Flags for the replay.
483  * @param rh Handle to pass to message transmit function.
484  */
485 typedef void
486 (*GNUNET_MULTICAST_ReplayCallback) (void *cls,
487                                     uint64_t fragment_id,
488                                     uint64_t message_id,
489                                     uint64_t flags,
490                                     struct GNUNET_MULTICAST_ReplayHandle *rh);
491
492
493 /** 
494  * Possible error codes during replay.
495  */
496 enum GNUNET_MULTICAST_ReplayErrorCode
497 {
498
499   /** 
500    * Everything is fine.
501    */
502   GNUNET_MULTICAST_REC_OK = 0,
503
504   /** 
505    * Message fragment has been discarded (likely transient message that was too old).
506    */
507   GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1,
508
509   /** 
510    * Fragment ID counter was larger than the highest counter this
511    * replay function has ever encountered; thus it is likely the
512    * origin never sent it and we're at the HEAD of the multicast
513    * stream as far as this node is concerned.
514    */
515   GNUNET_MULTICAST_REC_PAST_HEAD = 2,
516
517   /** 
518    * Internal error (i.e. database error).  Try some other peer.
519    */
520   GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3
521
522 };
523
524
525 /** 
526  * Replay a message from the multicast group.
527  *
528  * FIXME: use notify callbacks here too (or in a replay2() function),
529  *        to be able to use the replay functionality for state sync as well.
530  *
531  * @param rh Replay handle identifying which replay operation was requested.
532  * @param msg Replayed message fragment, NULL if unknown/error.
533  * @param ec Error code.
534  */
535 void
536 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
537                          const struct GNUNET_MULTICAST_MessageHeader *msg,
538                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
539
540
541 /** 
542  * Start a multicast group.
543  *
544  * Will advertise the origin in the P2P overlay network under the respective
545  * public key so that other peer can find this peer to join it.  Peers that
546  * issue GNUNET_MULTICAST_member_join() can then transmit a join request to
547  * either an existing group member (if the @a policy is permissive) or to
548  * the origin.  If the joining is approved, the member is cleared for @e replay
549  * and will begin to receive messages transmitted to the group.  If joining is
550  * disapproved, the failed candidate will be given a response.  Members in the
551  * group can send messages to the origin (one at a time).
552  *
553  * @param cfg Configuration to use.
554  * @param priv_key ECC key that will be used to sign messages for this
555  *        multicast session; public key is used to identify the multicast group;
556  *        FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
557  *        one in the future.
558  * @param policy Group policy specifying join and history restrictions.
559  *        FIXME: needed? Ít would be enough to have this on the PSYC layer, as
560  *        access control to enforce the policy is done by the membership test
561  *        and join request callbacks of the API.
562  * @param last_fragment_id Last fragment ID to continue counting fragments from
563  *        when restarting the origin.  0 for a new group.
564  * @param join_cb Function called to approve / disapprove joining of a peer.
565  * @param test_cb Function multicast can use to test group membership.
566  * @param replay_cb Function that can be called to replay a message.
567  * @param request_cb Function called with message fragments from group members.
568  * @param message_cb Function called with the message fragments sent to the
569  *        network by GNUNET_MULTICAST_origin_to_all().  These message fragments
570  *        should be stored for answering replay requests later.
571  * @param cls Closure for the various callbacks that follow.
572  * @return Handle for the origin, NULL on error.
573  */
574 struct GNUNET_MULTICAST_Origin *
575 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
576                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
577                                enum GNUNET_MULTICAST_GroupPolicy policy,
578                                uint64_t last_fragment_id,
579                                GNUNET_MULTICAST_JoinCallback join_cb,
580                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
581                                GNUNET_MULITCAST_ReplayCallback replay_cb,
582                                GNUNET_MULTICAST_RequestCallback request_cb,
583                                GNUNET_MULTICAST_MessageCallback message_cb,
584                                void *cls);
585
586
587 /** 
588  * Handle for a request to send a message to all multicast group members
589  * (from the origin).
590  */
591 struct GNUNET_MULTICAST_OriginMessageHandle;
592
593
594 /** 
595  * Send a message to the multicast group.
596  *
597  * @param origin Handle to the multicast group.
598  * @param message_id Application layer ID for the message.  Opaque to multicast.
599  * @param group_generation Group generation of the message.  Documented in
600  *             GNUNET_MULTICAST_MessageHeader.
601  * @param size Number of bytes to transmit.
602  *        FIXME: Needed? The end of the message can be flagged with a last fragment flag.
603  * @param notify Function to call to get the message.
604  * @param notify_cls Closure for @a notify.
605  * @return NULL on error (i.e. request already pending).
606  */
607 struct GNUNET_MULTICAST_OriginMessageHandle *
608 GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
609                                 uint64_t message_id,
610                                 uint64_t group_generation,
611                                 size_t size,
612                                 GNUNET_CONNECTION_TransmitReadyNotify notify,
613                                 void *notify_cls);
614
615
616 /** 
617  * Cancel request for message transmission to multicast group.
618  *
619  * @param mh Request to cancel.
620  */
621 void
622 GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginMessageHandle *mh);
623
624
625 /** 
626  * Stop a multicast group.
627  *
628  * @param origin Multicast group to stop.
629  */
630 void
631 GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
632
633
634 /** 
635  * Join a multicast group.
636  *
637  * The entity joining is always the local peer.  Further information about the
638  * candidate can be provided in the @a join_request message.  If the join fails, the
639  * @a message_cb is invoked with a (failure) response and then with NULL.  If
640  * the join succeeds, outstanding (state) messages and ongoing multicast
641  * messages will be given to the @a message_cb until the member decides to part
642  * the group.  The @a test_cb and @a replay_cb functions may be called at
643  * anytime by the multicast service to support relaying messages to other
644  * members of the group.
645  *
646  * @param cfg Configuration to use.
647  * @param group_key ECC public key that identifies the group to join.
648  * @param member_key ECC key that identifies the member and used to sign
649  *        requests sent to the origin.
650  * @param origin Peer ID of the origin to send unicast requsets to.  If NULL,
651  *        unicast requests are sent back via multiple hops on the reverse path
652  *        of multicast messages.
653  * @param relay_count Number of peers in the @a relays array.
654  * @param relays Peer identities of members of the group, which serve as relays
655  *        and can be used to join the group at. and send the @a join_request to.
656  *        If empty, the @a join_request is sent directly to the @a origin.
657  * @param join_request  Application-dependent join request to be passed to the peer
658  *        @a relay (might, for example, contain a user, bind user
659  *        identity/pseudonym to peer identity, application-level message to
660  *        origin, etc.).
661  * @param max_known_fragment_id Largest known message fragment ID to the replay
662  *        service; all messages with IDs larger than this ID will be replayed if
663  *        possible (lower IDs will be considered known and thus only
664  *        be replayed upon explicit request).
665  *        FIXME: needed? can be optional or moved to a separate function.
666  * @param join_cb Function called to approve / disapprove joining of a peer.
667  * @param test_cb Function multicast can use to test group membership.
668  * @param replay_cb Function that can be called to replay messages
669  *        this peer already knows from this group; NULL if this
670  *        client is unable to support replay.
671  * @param message_cb Function to be called for all message fragments we
672  *        receive from the group, excluding those our @a replay_cb
673  *        already has.
674  * @param cls Closure for callbacks.
675  * @return Handle for the member, NULL on error.
676  */
677 struct GNUNET_MULTICAST_Member *
678 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
679                               const struct GNUNET_CRYPTO_EccPublicKey *group_key,
680                               const struct GNUNET_CRYPTO_EccPrivateKey *member_key,
681                               const struct GNUNET_PeerIdentity *origin,
682                               size_t relay_count,
683                               const struct GNUNET_PeerIdentity *relays,
684                               const struct GNUNET_MessageHeader *join_request,
685                               uint64_t max_known_fragment_id,
686                               GNUNET_MULTICAST_JoinCallback join_cb,
687                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
688                               GNUNET_MULITCAST_ReplayCallback replay_cb,
689                               GNUNET_MULTICAST_MessageCallback message_cb,
690                               void *cls);
691
692
693 /** 
694  * Handle for a replay request.
695  */
696 struct GNUNET_MULTICAST_MemberReplayHandle;
697
698
699 /** 
700  * Request a message to be replayed.
701  *
702  * Useful if messages below the @e max_known_fragment_id given when joining are
703  * needed and not known to the client.
704  *
705  * @param member Membership handle.
706  * @param fragment_id ID of a message fragment that this client would like to
707           see replayed.
708  * @param message_id ID of a message that this client would like to see
709  *        replayed.  Typically only one of the @a fragment_id and @a message_id
710  *        is given.  Specifying a @a message_id would return the last fragment
711  *        of the message, which allows requesting the preceding fragments of the
712  *        message by looking at the @e fragment_delta header field.
713  * @param flags Additional flags for the replay request.  It is used & defined
714  *        by the replay callback.  E.g. the PSYC service would use this to
715  *        implement state synchronization.
716  * @param message_cb Function to be called for the replayed message.
717  * @param message_cb_cls Closure for @a message_cb.
718  * @return Replay request handle, NULL on error.
719  */
720 struct GNUNET_MULTICAST_MemberReplayHandle *
721 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
722                                         uint64_t fragment_id,
723                                         uint64_t message_id,
724                                         uint64_t flags,
725                                         GNUNET_MULTICAST_MessageCallback message_cb,
726                                         void *message_cb_cls);
727
728
729 /** 
730  * Cancel a replay request.
731  *
732  * @param rh Request to cancel.
733  */
734 void
735 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandle *rh);
736
737
738 /** 
739  * Part a multicast group.
740  *
741  * Disconnects from all group members and invalidates the @a member handle.
742  *
743  * An application-dependent part message can be transmitted beforehand using
744  * GNUNET_MULTICAST_member_to_origin())
745  *
746  * @param member Membership handle.
747  */
748 void
749 GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member);
750
751
752 /** 
753  * Handle for a message to be delivered from a member to the origin.
754  */
755 struct GNUNET_MULTICAST_MemberRequestHandle;
756
757
758 /** 
759  * Send a message to the origin of the multicast group.
760  * 
761  * @param member Membership handle.
762  * @param message_id Application layer ID for the message.  Opaque to multicast.
763  * @param size Number of bytes we want to send to origin.
764  * @param notify Callback to call to get the message.
765  * @param notify_cls Closure for @a notify.
766  * @return Handle to cancel request, NULL on error (i.e. request already pending).
767  */
768 struct GNUNET_MULTICAST_MemberRequestHandle *
769 GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
770                                    uint64_t message_id,
771                                    size_t size,
772                                    GNUNET_CONNECTION_TransmitReadyNotify notify,
773                                    void *notify_cls);
774
775
776 /** 
777  * Cancel request for message transmission to origin.
778  *
779  * @param rh Request to cancel.
780  */
781 void
782 GNUNET_MULTICAST_member_to_origin_cancel (struct GNUNET_MULTICAST_MemberRequestHandle *rh);
783
784
785 #if 0                           /* keep Emacsens' auto-indent happy */
786 {
787 #endif
788 #ifdef __cplusplus
789 }
790 #endif
791
792 /* ifndef GNUNET_MULTICAST_SERVICE_H */
793 #endif
794 /* end of gnunet_multicast_service.h */