b4f9bc099bbbf3940ceb3ad3bb194d0123242dcd
[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 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_id Identity of the member that we want to test.
416  * @param fragment_id Message fragment ID for which we want to do the test.
417  * @param mth Handle to give to GNUNET_MULTICAST_membership_test_answer().
418  */
419 typedef void
420 (*GNUNET_MULTICAST_MembershipTestCallback) (void *cls,
421                                             const struct GNUNET_CRYPTO_EccPublicKey *member_key,
422                                             uint64_t fragment_id,
423                                             struct GNUNET_MULTICAST_MembershipTestHandle *mth);
424
425
426 /** 
427  * Function called whenever a group member has transmitted a request
428  * to the origin (other than joining or leaving).
429  *
430  * @param cls Closure (set from GNUNET_MULTICAST_origin_start).
431  * @param sender Identity of the sender.
432  * @param req Request to the origin.
433  * @param flags Flags for the request.
434  */
435 typedef void
436 (*GNUNET_MULTICAST_RequestCallback) (void *cls,
437                                      const struct GNUNET_EccPublicKey *member_key,
438                                      const struct GNUNET_MessageHeader *req,
439                                      enum GNUNET_MULTICAST_MessageFlags flags);
440
441
442 /** 
443  * Function called whenever a group member is receiving a message fragment from
444  * the origin.
445  *
446  * If admission to the group is denied, this function is called once with the
447  * response of the @e origin (as given to GNUNET_MULTICAST_join_decision()) and
448  * then a second time with NULL to indicate that the connection failed for good.
449  *
450  * @param cls Closure (set from GNUNET_MULTICAST_member_join())
451  * @param msg Message from the origin, NULL if the origin shut down
452  *        (or we were kicked out, and we should thus call
453  *        GNUNET_MULTICAST_member_part() next)
454  */
455 typedef void
456 (*GNUNET_MULTICAST_MessageCallback) (void *cls,
457                                      const struct GNUNET_MULTICAST_MessageHeader *msg);
458
459
460 /** 
461  * Opaque handle to a replay request from the multicast service.
462  */
463 struct GNUNET_MULTICAST_ReplayHandle;
464
465
466 /** 
467  * Functions with this signature are called whenever the multicast service needs
468  * a message to be replayed.
469  *
470  * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
471  * (with a message or an error); however, if the origin is destroyed or the
472  * group is left, the replay handle must no longer be used.
473  *
474  * @param cls Closure (set from GNUNET_MULTICAST_origin_start()
475  *            or GNUNET_MULTICAST_member_join()).
476  * @param fragment_id Which message fragment should be replayed.
477  * @param rh Handle to pass to message transmit function.
478  */
479 typedef void
480 (*GNUNET_MULTICAST_ReplayCallback) (void *cls,
481                                     uint64_t fragment_id,
482                                     struct GNUNET_MULTICAST_ReplayHandle *rh);
483
484
485 /** 
486  * Possible error codes during replay.
487  */
488 enum GNUNET_MULTICAST_ReplayErrorCode
489 {
490
491   /** 
492    * Everything is fine.
493    */
494   GNUNET_MULTICAST_REC_OK = 0,
495
496   /** 
497    * Message fragment has been discarded (likely transient message that was too old).
498    */
499   GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1,
500
501   /** 
502    * Fragment ID counter was larger than the highest counter this
503    * replay function has ever encountered; thus it is likely the
504    * origin never sent it and we're at the HEAD of the multicast
505    * stream as far as this node is concerned.
506    */
507   GNUNET_MULTICAST_REC_PAST_HEAD = 2,
508
509   /** 
510    * Internal error (i.e. database error).  Try some other peer.
511    */
512   GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3
513
514 };
515
516
517 /** 
518  * Replay a message from the multicast group.
519  *
520  * @param rh Replay handle identifying which replay operation was requested.
521  * @param msg Replayed message fragment, NULL if unknown/error.
522  * @param ec Error code.
523  */
524 void
525 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
526                          const struct GNUNET_MULTICAST_MessageHeader *msg,
527                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
528
529
530 /** 
531  * Start a multicast group.
532  *
533  * Will advertise the origin in the P2P overlay network under the respective
534  * public key so that other peer can find this peer to join it.  Peers that
535  * issue GNUNET_MULTICAST_member_join() can then transmit a join request to
536  * either an existing group member (if the @a policy is permissive) or to
537  * the origin.  If the joining is approved, the member is cleared for @e replay
538  * and will begin to receive messages transmitted to the group.  If joining is
539  * disapproved, the failed candidate will be given a response.  Members in the
540  * group can send messages to the origin (one at a time).
541  *
542  * @param cfg Configuration to use.
543  * @param priv_key ECC key that will be used to sign messages for this
544  *        multicast session; public key is used to identify the multicast group;
545  *        FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
546  *        one in the future.
547  * @param policy Group policy specifying join and history restrictions.
548  * @param last_fragment_id Last fragment ID to continue counting fragments from
549  *        when restarting the origin.  0 for a new group.
550  * @param join_cb Function called to approve / disapprove joining of a peer.
551  * @param test_cb Function multicast can use to test group membership.
552  * @param replay_cb Function that can be called to replay a message.
553  * @param request_cb Function called with message fragments from group members.
554  * @param message_cb Function called with the message fragments sent to the
555  *        network by GNUNET_MULTICAST_origin_to_all().  These message fragments
556  *        should be stored for answering replay requests later.
557  * @param cls Closure for the various callbacks that follow.
558  * @return Handle for the origin, NULL on error.
559  */
560 struct GNUNET_MULTICAST_Origin *
561 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
562                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
563                                enum GNUNET_MULTICAST_GroupPolicy policy,
564                                uint64_t last_fragment_id,
565                                GNUNET_MULTICAST_JoinCallback join_cb,
566                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
567                                GNUNET_MULITCAST_ReplayCallback replay_cb,
568                                GNUNET_MULTICAST_RequestCallback request_cb,
569                                GNUNET_MULTICAST_MessageCallback message_cb,
570                                void *cls);
571
572
573 /** 
574  * Handle for a request to send a message to all multicast group members
575  * (from the origin).
576  */
577 struct GNUNET_MULTICAST_OriginMessageHandle;
578
579
580 /** 
581  * Send a message to the multicast group.
582  *
583  * @param origin Handle to the multicast group.
584  * @param message_id Application layer ID for the message.  Opaque to multicast.
585  * @param group_generation Group generation of the message.  Documented in
586  *             GNUNET_MULTICAST_MessageHeader.
587  * @param size Number of bytes to transmit.
588  *        FIXME: Needed? The end of the message can be flagged with a last fragment flag.
589  * @param notify Function to call to get the message.
590  * @param notify_cls Closure for @a notify.
591  * @return NULL on error (i.e. request already pending).
592  */
593 struct GNUNET_MULTICAST_OriginMessageHandle *
594 GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
595                                 uint64_t message_id,
596                                 uint64_t group_generation,
597                                 size_t size,
598                                 GNUNET_CONNECTION_TransmitReadyNotify notify,
599                                 void *notify_cls);
600
601
602 /** 
603  * Cancel request for message transmission to multicast group.
604  *
605  * @param mh Request to cancel.
606  */
607 void
608 GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginMessageHandle *mh);
609
610
611 /** 
612  * Stop a multicast group.
613  *
614  * @param origin Multicast group to stop.
615  */
616 void
617 GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
618
619
620 /** 
621  * Join a multicast group.
622  *
623  * The entity joining is always the local peer.  Further information about the
624  * candidate can be provided in the @a join_request message.  If the join fails, the
625  * @a message_cb is invoked with a (failure) response and then with NULL.  If
626  * the join succeeds, outstanding (state) messages and ongoing multicast
627  * messages will be given to the @a message_cb until the member decides to part
628  * the group.  The @a test_cb and @a replay_cb functions may be called at
629  * anytime by the multicast service to support relaying messages to other
630  * members of the group.
631  *
632  * @param cfg Configuration to use.
633  * @param group_key ECC public key that identifies the group to join.
634  * @param member_key ECC key that identifies the member and used to sign
635  *        requests sent to the origin.
636  * @param origin Peer ID of the origin to send unicast requsets to.  If NULL,
637  *        unicast requests are sent back via multiple hops on the reverse path
638  *        of multicast messages.
639  * @param relay_count Number of peers in the @a relays array.
640  * @param relays Peer identities of members of the group, which serve as relays
641  *        and can be used to join the group at. and send the @a join_request to.
642  *        If empty, the @a join_request is sent directly to the @a origin.
643  * @param join_request  Application-dependent join request to be passed to the peer
644  *        @a relay (might, for example, contain a user, bind user
645  *        identity/pseudonym to peer identity, application-level message to
646  *        origin, etc.).
647  * @param max_known_fragment_id Largest known message fragment ID to the replay
648  *        service; all messages with IDs larger than this ID will be replayed if
649  *        possible (lower IDs will be considered known and thus only
650  *        be replayed upon explicit request).
651  *        FIXME: needed? can be optional or moved to a separate function.
652  * @param join_cb Function called to approve / disapprove joining of a peer.
653  * @param test_cb Function multicast can use to test group membership.
654  * @param replay_cb Function that can be called to replay messages
655  *        this peer already knows from this group; NULL if this
656  *        client is unable to support replay.
657  * @param message_cb Function to be called for all message fragments we
658  *        receive from the group, excluding those our @a replay_cb
659  *        already has.
660  * @param cls Closure for callbacks.
661  * @return Handle for the member, NULL on error.
662  */
663 struct GNUNET_MULTICAST_Member *
664 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
665                               const struct GNUNET_CRYPTO_EccPublicKey *group_key,
666                               const struct GNUNET_CRYPTO_EccPrivateKey *member_key,
667                               const struct GNUNET_PeerIdentity *origin,
668                               size_t relay_count,
669                               const struct GNUNET_PeerIdentity *relays,
670                               const struct GNUNET_MessageHeader *join_request,
671                               uint64_t max_known_fragment_id,
672                               GNUNET_MULTICAST_JoinCallback join_cb,
673                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
674                               GNUNET_MULITCAST_ReplayCallback replay_cb,
675                               GNUNET_MULTICAST_MessageCallback message_cb,
676                               void *cls);
677
678
679 /** 
680  * Handle for a replay request.
681  */
682 struct GNUNET_MULTICAST_MemberReplayHandle;
683
684
685 /** 
686  * Request a message to be replayed.
687  *
688  * Useful if messages below the @e max_known_fragment_id given when joining are
689  * needed and not known to the client.
690  *
691  * @param member Membership handle.
692  * @param message_id ID of a message that this client would like to see replayed.
693  * @param message_cb Function to be called for the replayed message.
694  * @param message_cb_cls Closure for @a message_cb.
695  * @return Replay request handle, NULL on error.
696  */
697 struct GNUNET_MULTICAST_MemberReplayHandle *
698 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
699                                         uint64_t message_id,
700                                         GNUNET_MULTICAST_MessageCallback message_cb,
701                                         void *message_cb_cls);
702
703
704 /** 
705  * Cancel a replay request.
706  *
707  * @param rh Request to cancel.
708  */
709 void
710 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandle *rh);
711
712
713 /** 
714  * Part a multicast group.
715  *
716  * Disconnects from all group members and invalidates the @a member handle.
717  *
718  * An application-dependent part message can be transmitted beforehand using
719  * GNUNET_MULTICAST_member_to_origin())
720  *
721  * @param member Membership handle.
722  */
723 void
724 GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member);
725
726
727 /** 
728  * Handle for a message to be delivered from a member to the origin.
729  */
730 struct GNUNET_MULTICAST_MemberRequestHandle;
731
732
733 /** 
734  * Send a message to the origin of the multicast group.
735  * 
736  * @param member Membership handle.
737  * @param message_id Application layer ID for the message.  Opaque to multicast.
738  * @param size Number of bytes we want to send to origin.
739  * @param notify Callback to call to get the message.
740  * @param notify_cls Closure for @a notify.
741  * @return Handle to cancel request, NULL on error (i.e. request already pending).
742  */
743 struct GNUNET_MULTICAST_MemberRequestHandle *
744 GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
745                                    uint64_t message_id,
746                                    size_t size,
747                                    GNUNET_CONNECTION_TransmitReadyNotify notify,
748                                    void *notify_cls);
749
750
751 /** 
752  * Cancel request for message transmission to origin.
753  *
754  * @param rh Request to cancel.
755  */
756 void
757 GNUNET_MULTICAST_member_to_origin_cancel (struct GNUNET_MULTICAST_MemberRequestHandle *rh);
758
759
760 #if 0                           /* keep Emacsens' auto-indent happy */
761 {
762 #endif
763 #ifdef __cplusplus
764 }
765 #endif
766
767 /* ifndef GNUNET_MULTICAST_SERVICE_H */
768 #endif
769 /* end of gnunet_multicast_service.h */