multicast: no state_delta
[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    * Signature of the multicast message fragment.
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   /** 
221    * Header for the message body.
222    *
223    * Three message types are specifically understood by multicast, namely "peer
224    * join", "peer part", and "group terminated".  Multicast will use those
225    * messages to update its list of candidates for content distribution.  All
226    * other message types are application-specific.
227    *
228    * FIXME: Needed? There's no message type argument of origin_to_all(),
229    *        PSYC does not need it, but could be added.
230    */
231   struct GNUNET_MessageHeader body;
232
233   /* Followed by message body. */
234 };
235
236
237 /** 
238  * Header of a request from a member to the origin.
239  *
240  * FIXME: this is going to be internal.
241  */
242 struct GNUNET_MULTICAST_RequestHeader
243 {
244   /** 
245    * Header for all requests from a member to the origin.
246    */
247   struct GNUNET_MessageHeader header;
248
249   /**
250    * Public key of the group.
251    */
252   struct GNUNET_CRYPTO_ECCPublicKey pub_key;
253
254   /**
255    * Flags for this request.
256    */
257   enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
258
259   /** 
260    * Header for the request body.
261    *
262    * Two request types are specifically understood by multicast, namely "peer
263    * join", "peer part".  Multicast will use those messages to update its list
264    * of candidates for content distribution.  All other message types are
265    * application-specific.
266    */
267   struct GNUNET_MessageHeader body;
268
269   /* Followed by request body. */
270 };
271
272 GNUNET_NETWORK_STRUCT_END
273
274
275 /** 
276  * Handle that identifies a join request.
277  *
278  * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the
279  * corresponding calls to GNUNET_MULTICAST_join_decision().
280  */
281 struct GNUNET_MULTICAST_JoinHandle;
282
283
284 /** 
285  * Function to call with the decision made for a join request.
286  *
287  * Must be called once and only once in response to an invocation of the
288  * #GNUNET_MULTICAST_JoinCallback.
289  *
290  * @param jh Join request handle.
291  * @param is_admitted #GNUNET_YES if joining is approved,
292  *        #GNUNET_NO if it is disapproved
293  * @param relay_count Number of relays given.
294  * @param relays Array of suggested peers that might be useful relays to use
295  *        when joining the multicast group (essentially a list of peers that
296  *        are already part of the multicast group and might thus be willing
297  *        to help with routing).  If empty, only this local peer (which must
298  *        be the multicast origin) is a good candidate for building the
299  *        multicast tree.  Note that it is unnecessary to specify our own
300  *        peer identity in this array.
301  * @param join_response Message to send in response to the joining peer;
302  *        can also be used to redirect the peer to a different group at the
303  *        application layer; this response is to be transmitted to the
304  *        peer that issued the request even if admission is denied.
305  */
306 void
307 GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
308                                 int is_admitted,
309                                 unsigned int relay_count,
310                                 const struct GNUNET_PeerIdentity *relays,
311                                 const struct GNUNET_MessageHeader *join_response);
312
313
314 /** 
315  * Method called whenever another peer wants to join the multicast group.
316  *
317  * Implementations of this function must call GNUNET_MULTICAST_join_decision()
318  * with the decision.
319  *
320  * @param cls Closure.
321  * @param peer Identity of the peer that wants to join.
322  * @param join_req Application-dependent join message from the new user
323  *        (might, for example, contain a user,
324  *        bind user identity/pseudonym to peer identity, application-level
325  *        message to origin, etc.).
326  * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison().
327  */
328 typedef void (*GNUNET_MULTICAST_JoinCallback)(void *cls,
329                                               const struct GNUNET_PeerIdentity *peer,
330                                               const struct GNUNET_MessageHeader *join_req,
331                                               struct GNUNET_MULTICAST_JoinHandle *jh);
332
333
334 /** 
335  * Handle to pass back for the answer of a membership test.
336  */
337 struct GNUNET_MULTICAST_MembershipTestHandle;
338
339
340 /** 
341  * Call informing multicast about the decision taken for membership test.
342  *
343  * @param mth Handle that was given for the query.
344  * @param decision #GNUNET_YES if peer was a member, #GNUNET_NO if peer was not a member,
345  *         #GNUNET_SYSERR if we cannot answer the membership test.
346  */
347 void
348 GNUNET_MULTICAST_membership_test_answer (struct GNUNET_MULTICAST_MembershipTestHandle *mth,
349                                          int decision);
350
351
352 /** 
353  * Method called to test if a member was in the group at a particular time.
354  *
355  * It is called when a replay request is received to determine if the requested
356  * message can be replayed.
357  *
358  * @param cls Closure.
359  * @param peer Identity of the peer that we want to test.
360  * @param fragment_id Message fragment ID for which we want to do the test.
361  * @param mth Handle to give to GNUNET_MULTICAST_membership_test_answer().
362  */
363 typedef void (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
364                                                         const struct GNUNET_PeerIdentity *peer,
365                                                         uint64_t fragment_id,
366                                                         struct GNUNET_MULTICAST_MembershipTestHandle *mth);
367
368
369 /** 
370  * Function called whenever a group member has transmitted a request
371  * to the origin (other than joining or leaving).
372  *
373  * @param cls Closure (set from GNUNET_MULTICAST_origin_start).
374  * @param sender Identity of the sender.
375  * @param req Request to the origin.
376  * @param flags Flags for the request.
377  */
378 typedef void (*GNUNET_MULTICAST_RequestCallback) (void *cls,
379                                                   const struct GNUNET_PeerIdentity *sender,
380                                                   const struct GNUNET_MessageHeader *req,
381                                                   enum GNUNET_MULTICAST_MessageFlags flags);
382
383
384 /** 
385  * Function called whenever a group member is receiving a message fragment from
386  * the origin.
387  *
388  * If admission to the group is denied, this function is called once with the
389  * response of the @e origin (as given to GNUNET_MULTICAST_join_decision()) and
390  * then a second time with NULL to indicate that the connection failed for good.
391  *
392  * @param cls Closure (set from GNUNET_MULTICAST_member_join())
393  * @param msg Message from the origin, NULL if the origin shut down
394  *        (or we were kicked out, and we should thus call
395  *        GNUNET_MULTICAST_member_part() next)
396  */
397 typedef void (*GNUNET_MULTICAST_MessageCallback) (void *cls,
398                                                   const struct GNUNET_MULTICAST_MessageHeader *msg);
399
400
401 /** 
402  * Opaque handle to a replay request from the multicast service.
403  */
404 struct GNUNET_MULTICAST_ReplayHandle;
405
406
407 /** 
408  * Functions with this signature are called whenever the multicast service needs
409  * a message to be replayed.
410  *
411  * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
412  * (with a message or an error); however, if the origin is destroyed or the
413  * group is left, the replay handle must no longer be used.
414  *
415  * @param cls Closure (set from GNUNET_MULTICAST_origin_start()
416  *            or GNUNET_MULTICAST_member_join()).
417  * @param fragment_id Which message fragment should be replayed.
418  * @param rh Handle to pass to message transmit function.
419  */
420 typedef void (*GNUNET_MULTICAST_ReplayCallback) (void *cls,
421                                                  uint64_t fragment_id,
422                                                  struct GNUNET_MULTICAST_ReplayHandle *rh);
423
424
425 /** 
426  * Possible error codes during replay.
427  */
428 enum GNUNET_MULTICAST_ReplayErrorCode
429 {
430
431   /** 
432    * Everything is fine.
433    */
434   GNUNET_MULTICAST_REC_OK = 0,
435
436   /** 
437    * Message fragment has been discarded (likely transient message that was too old).
438    */
439   GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1,
440
441   /** 
442    * Fragment ID counter was larger than the highest counter this
443    * replay function has ever encountered; thus it is likely the
444    * origin never sent it and we're at the HEAD of the multicast
445    * stream as far as this node is concerned.
446    */
447   GNUNET_MULTICAST_REC_PAST_HEAD = 2,
448
449   /** 
450    * Internal error (i.e. database error).  Try some other peer.
451    */
452   GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3
453
454 };
455
456
457 /** 
458  * Replay a message from the multicast group.
459  *
460  * @param rh Replay handle identifying which replay operation was requested.
461  * @param msg Replayed message fragment, NULL if unknown/error.
462  * @param ec Error code.
463  */
464 void
465 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
466                          const struct GNUNET_MULTICAST_MessageHeader *msg,
467                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
468
469
470 /** 
471  * Start a multicast group.
472  *
473  * Will advertise the origin in the P2P overlay network under the respective
474  * public key so that other peer can find this peer to join it.  Peers that
475  * issue GNUNET_MULTICAST_member_join() can then transmit a join request to
476  * either an existing group member (if the @a policy is permissive) or to
477  * the origin.  If the joining is approved, the member is cleared for @e replay
478  * and will begin to receive messages transmitted to the group.  If joining is
479  * disapproved, the failed candidate will be given a response.  Members in the
480  * group can send messages to the origin (one at a time).
481  *
482  * @param cfg Configuration to use.
483  * @param priv_key ECC key that will be used to sign messages for this
484  *        multicast session; public key is used to identify the multicast group;
485  *        FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
486  *        one in the future.
487  * @param policy Group policy specifying join and history restrictions.
488  * @param last_fragment_id Last fragment ID to continue counting fragments from
489  *        when restarting the origin.  0 for a new group.
490  * @param join_cb Function called to approve / disapprove joining of a peer.
491  * @param test_cb Function multicast can use to test group membership.
492  * @param replay_cb Function that can be called to replay a message.
493  * @param request_cb Function called with message fragments from group members.
494  * @param message_cb Function called with the message fragments sent to the
495  *        network by GNUNET_MULTICAST_origin_to_all().  These message fragments
496  *        should be stored for answering replay requests later.
497  * @param cls Closure for the various callbacks that follow.
498  * @return Handle for the origin, NULL on error.
499  */
500 struct GNUNET_MULTICAST_Origin *
501 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
502                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
503                                enum GNUNET_MULTICAST_GroupPolicy policy,
504                                uint64_t last_fragment_id,
505                                GNUNET_MULTICAST_JoinCallback join_cb,
506                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
507                                GNUNET_MULITCAST_ReplayCallback replay_cb,
508                                GNUNET_MULTICAST_RequestCallback request_cb,
509                                GNUNET_MULTICAST_MessageCallback message_cb,
510                                void *cls);
511
512
513 /** 
514  * Handle for a request to send a message to all multicast group members
515  * (from the origin).
516  */
517 struct GNUNET_MULTICAST_OriginMessageHandle;
518
519
520 /** 
521  * Send a message to the multicast group.
522  *
523  * @param origin Handle to the multicast group.
524  * @param message_id Application layer ID for the message.  Opaque to multicast.
525  * @param group_generation Group generation of the message.  Documented in
526  *             GNUNET_MULTICAST_MessageHeader.
527  * @param size Number of bytes to transmit.
528  *        FIXME: Needed? The end of the message can be flagged with a last fragment flag.
529  * @param notify Function to call to get the message.
530  * @param notify_cls Closure for @a notify.
531  * @return NULL on error (i.e. request already pending).
532  */
533 struct GNUNET_MULTICAST_OriginMessageHandle *
534 GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
535                                 uint64_t message_id,
536                                 uint64_t group_generation,
537                                 size_t size,
538                                 GNUNET_CONNECTION_TransmitReadyNotify notify,
539                                 void *notify_cls);
540
541
542 /** 
543  * Cancel request for message transmission to multicast group.
544  *
545  * @param mh Request to cancel.
546  */
547 void
548 GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginMessageHandle *mh);
549
550
551 /** 
552  * Stop a multicast group.
553  *
554  * @param origin Multicast group to stop.
555  */
556 void
557 GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
558
559
560 /** 
561  * Join a multicast group.
562  *
563  * The entity joining is always the local peer.  Further information about the
564  * candidate can be provided in the @a join_request message.  If the join fails, the
565  * @a message_cb is invoked with a (failure) response and then with NULL.  If
566  * the join succeeds, outstanding (state) messages and ongoing multicast
567  * messages will be given to the @a message_cb until the member decides to part
568  * the group.  The @a test_cb and @a replay_cb functions may be called at
569  * anytime by the multicast service to support relaying messages to other
570  * members of the group.
571  *
572  * @param cfg Configuration to use.
573  * @param pub_key ECC key that identifies the group.
574  * @param origin Peer ID of the origin to send unicast requsets to.  If NULL,
575  *        unicast requests are sent back via multiple hops on the reverse path
576  *        of multicast messages.
577  * @param relay_count Number of peers in the @a relays array.
578  * @param relays Peer identities of members of the group, which serve as relays
579  *        and can be used to join the group at. and send the @a join_request to.
580  *        If empty, the @a join_request is sent directly to the @a origin.
581  * @param join_request  Application-dependent join request to be passed to the peer
582  *        @a relay (might, for example, contain a user, bind user
583  *        identity/pseudonym to peer identity, application-level message to
584  *        origin, etc.).
585  * @param max_known_fragment_id Largest known message fragment ID to the replay
586  *        service; all messages with IDs larger than this ID will be replayed if
587  *        possible (lower IDs will be considered known and thus only
588  *        be replayed upon explicit request).
589  *        FIXME: needed? can be optional or moved to a separate function.
590  * @param join_cb Function called to approve / disapprove joining of a peer.
591  * @param test_cb Function multicast can use to test group membership.
592  * @param replay_cb Function that can be called to replay messages
593  *        this peer already knows from this group; NULL if this
594  *        client is unable to support replay.
595  * @param message_cb Function to be called for all message fragments we
596  *        receive from the group, excluding those our @a replay_cb
597  *        already has.
598  * @param cls Closure for callbacks.
599  * @return Handle for the member, NULL on error.
600  */
601 struct GNUNET_MULTICAST_Member *
602 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
603                               const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
604                               const struct GNUNET_PeerIdentity *origin,
605                               size_t relay_count,
606                               const struct GNUNET_PeerIdentity *relays,
607                               const struct GNUNET_MessageHeader *join_request,
608                               uint64_t max_known_fragment_id,
609                               GNUNET_MULTICAST_JoinCallback join_cb,
610                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
611                               GNUNET_MULITCAST_ReplayCallback replay_cb,
612                               GNUNET_MULTICAST_MessageCallback message_cb,
613                               void *cls);
614
615
616 /** 
617  * Handle for a replay request.
618  */
619 struct GNUNET_MULTICAST_MemberReplayHandle;
620
621
622 /** 
623  * Request a message to be replayed.
624  *
625  * Useful if messages below the @e max_known_*_id's given when joining are
626  * needed and not known to the client.
627  *
628  * @param member Membership handle.
629  * @param message_id ID of a message that this client would like to see replayed.
630  * @param message_cb Function to be called for the replayed message.
631  * @param message_cb_cls Closure for @a message_cb.
632  * @return Replay request handle, NULL on error.
633  */
634 struct GNUNET_MULTICAST_MemberReplayHandle *
635 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
636                                         uint64_t message_id,
637                                         GNUNET_MULTICAST_MessageCallback message_cb,
638                                         void *message_cb_cls);
639
640
641 /** 
642  * Cancel a replay request.
643  *
644  * @param rh Request to cancel.
645  */
646 void
647 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandle *rh);
648
649
650 /** 
651  * Part a multicast group.
652  *
653  * Disconnects from all group members and invalidates the @a member handle.
654  *
655  * An application-dependent part message can be transmitted beforehand using
656  * GNUNET_MULTICAST_member_to_origin())
657  *
658  * @param member Membership handle.
659  */
660 void
661 GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member);
662
663
664 /** 
665  * Handle for a message to be delivered from a member to the origin.
666  */
667 struct GNUNET_MULTICAST_MemberRequestHandle;
668
669
670 /** 
671  * Send a message to the origin of the multicast group.
672  * 
673  * @param member Membership handle.
674  * @param size Number of bytes we want to send to origin.
675  * @param notify Callback to call to get the message.
676  * @param notify_cls Closure for @a notify.
677  * @return Handle to cancel request, NULL on error (i.e. request already pending).
678  */
679 struct GNUNET_MULTICAST_MemberRequestHandle *
680 GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
681                                    size_t size,
682                                    GNUNET_CONNECTION_TransmitReadyNotify notify,
683                                    void *notify_cls);
684
685
686 /** 
687  * Cancel request for message transmission to origin.
688  *
689  * @param rh Request to cancel.
690  */
691 void
692 GNUNET_MULTICAST_member_to_origin_cancel (struct GNUNET_MULTICAST_MemberRequestHandle *rh);
693
694
695 /** 
696  * Handle to access multicast group operations for both the origin and members.
697  */
698 struct GNUNET_MULTICAST_Group;
699
700
701 /** 
702  * Convert a group @a origin to a @e group handle to access the @e group APIs.
703  *
704  * @param origin Group origin handle.
705  * @return Group handle, valid for as long as @a origin is valid.
706  */
707 struct GNUNET_MULTICAST_Group *
708 GNUNET_MULTICAST_origin_get_group (struct GNUNET_MULTICAST_Origin *origin);
709
710
711 /** 
712  * Convert @a member to a @e group handle to access the @e group APIs.
713  *
714  * @param member Member handle.
715  * @return Group handle, valid for as long as @a member is valid.
716  */
717 struct GNUNET_MULTICAST_Group *
718 GNUNET_MULTICAST_member_get_group (struct GNUNET_MULTICAST_Member *member);
719
720
721 /**
722  * Remove a peer from the group.
723  *
724  * After a message was received notifying about a leaving member, remove the
725  * member from the multicast group.  Fragments with a greater @a message_id than
726  * the specified one won't be transmitted to the member anymore, but the
727  * transmission of lower or equal ones will still be performed.
728  */
729 void
730 GNUNET_MULTICAST_group_member_remove (struct GNUNET_MULTICAST_Group *group,
731                                       const struct GNUNET_PeerIdentity *peer,
732                                       uint64_t message_id);
733
734
735 #if 0                           /* keep Emacsens' auto-indent happy */
736 {
737 #endif
738 #ifdef __cplusplus
739 }
740 #endif
741
742 /* ifndef GNUNET_MULTICAST_SERVICE_H */
743 #endif
744 /* end of gnunet_multicast_service.h */