58f5c4fbe512b5f2cb4cf49251cf972c4d40a209
[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  * Group membership policies.
60  */
61 enum GNUNET_MULTICAST_JoinPolicy
62 {
63   /**
64    * Anyone can join the group, without announcing his presence;
65    * all messages are always public and can be distributed freely.
66    * Joins may be announced, but this is not required.
67    */
68   GNUNET_MULTICAST_JP_ANONYMOUS = 0,
69
70   /** 
71    * Origin must approve membership to the group, messages must only be
72    * distributed to current group members.  This includes the group
73    * state as well as transient messages.
74    */
75   GNUNET_MULTICAST_JP_PRIVATE = 1,
76
77 #if IDEAS_FOR_FUTURE
78   /** 
79    * Anyone can freely join the group (no approval required); however,
80    * transient messages must only be distributed to current group
81    * members, so the origin must still acknowledge that the member
82    * joined before transient messages are delivered.  As approval is
83    * guaranteed, the presistent group state can be synchronized freely
84    * immediately, prior to origin confirmation.
85    */
86   GNUNET_MULTICAST_JP_OPEN = 2,
87
88   /**
89    * Origin must approve membership to the group, but past messages can be
90    * freely distributed to members.
91    */
92   GNUNET_MULTICAST_JP_CLOSED = 3,
93 #endif
94
95 };
96
97 enum GNUNET_MULTICAST_MessageFlags
98 {
99   /**
100    * First fragment of a message.
101    */
102   GNUNET_MULTICAST_MESSAGE_FIRST_FRAGMENT = 1 << 0,
103
104   /**
105    * Last fragment of a message.
106    */
107   GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT = 1 << 1,
108
109   /** 
110    * OR'ed flags if message is not fragmented.
111    */
112   GNUNET_MULTICAST_MESSAGE_NOT_FRAGMENTED
113     = GNUNET_MULTICAST_MESSAGE_FIRST_FRAGMENT
114     | GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT
115 };
116
117
118 GNUNET_NETWORK_STRUCT_BEGIN
119
120 /** 
121  * Header of a multicast message fragment.
122  *
123  * This format is public as the replay mechanism must replay message fragments using the
124  * same format.  This is needed as we want to integrity-check message fragments within
125  * the multicast layer to avoid multicasting mal-formed messages.
126  */
127 struct GNUNET_MULTICAST_MessageHeader
128 {
129
130   /** 
131    * Header for all multicast message fragments from the origin.
132    */
133   struct GNUNET_MessageHeader header;
134
135   /** 
136    * Number of hops this message fragment has taken since the origin.
137    *
138    * Helpful to determine shortest paths to the origin for responses among
139    * honest peers; updated at each hop and thus not signed and not secure.
140    */
141   uint32_t hop_counter GNUNET_PACKED;
142
143   /** 
144    * ECC signature of the message fragment.
145    *
146    * Signature must match the public key of the multicast group.
147    */
148   struct GNUNET_CRYPTO_EccSignature signature;
149
150   /** 
151    * Signature of the multicast message fragment.
152    */
153   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
154
155   /** 
156    * Number of the message fragment, monotonically increasing.
157    */
158   uint64_t fragment_id GNUNET_PACKED;
159
160   /** 
161    * Number of the message this fragment belongs to.
162    */
163   uint64_t message_id GNUNET_PACKED;
164
165   /** 
166    * Byte offset of this @e fragment of the @e message.
167    */
168   uint64_t fragment_offset GNUNET_PACKED;
169
170   /** 
171    * Counter that monotonically increases whenever a member parts the group.
172    *
173    * It has significance in case of replay requests: when a member has missed
174    * messages and gets a replay request: in this case if the @a group_generation
175    * is still the same before and after the missed messages, it means that no
176    * @e join or @e part operations happened during the missed messages.
177    */
178   uint64_t group_generation GNUNET_PACKED;
179
180   /** 
181    * Difference between the current @a fragment_id and the @a fragment_id of the
182    * preceeding non-transient message.
183    * 
184    * Zero for transient messages, @c UINT64_MAX for the first message, or any
185    * other message creating a full state reset by the origin.  By subtracting
186    * @a state_delta from @a fragment_id, it is possible to calculate the message
187    * ID of the preceeding non-transient message and thus quickly traverse all
188    * state changes up to the last full state reset by the origin.  This is
189    * useful as it allows joining clients to quickly reassemble the state while
190    * skipping over transient messages (and doing so without having to trust
191    * intermediaries to do it right, as the indices in the chain are signed).  If
192    * the state chain is getting too long, the origin can choose to originate a
193    * state message with a state_delta of UINT64_MAX, thereby starting a new
194    * chain.  The origin will then have to re-create the full state with state
195    * update messages following the state reset message.
196    *
197    * Open question: needed in multicast, or just have this in PSYC; still might
198    * be useful for selective fetching of messages.  Still, that again should
199    * that not be done by PSYC?
200    */
201   uint64_t state_delta GNUNET_PACKED;
202
203   /**
204    * Flags for this message.
205    */
206   enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
207
208   /** 
209    * Header for the message body.
210    *
211    * Three message types are specifically understood by multicast, namely "peer
212    * join", "peer part", and "group terminated".  Multicast will use those
213    * messages to update its list of candidates for content distribution.  All
214    * other message types are application-specific.
215    */
216   struct GNUNET_MessageHeader body;
217
218   /* Followed by message body. */
219 };
220
221
222 /** 
223  * Header of a request from a member to the origin.
224  *
225  * FIXME: this is going to be internal.
226  */
227 struct GNUNET_MULTICAST_RequestHeader
228 {
229   /** 
230    * Header for all requests from a member to the origin.
231    */
232   struct GNUNET_MessageHeader header;
233
234   /**
235    * Public key of the group.
236    */
237   struct GNUNET_CRYPTO_ECCPublicKey pub_key;
238
239   /**
240    * Flags for this request.
241    */
242   enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
243
244   /** 
245    * Header for the request body.
246    *
247    * Two request types are specifically understood by multicast, namely "peer
248    * join", "peer part".  Multicast will use those messages to update its list
249    * of candidates for content distribution.  All other message types are
250    * application-specific.
251    */
252   struct GNUNET_MessageHeader body;
253
254   /* Followed by request body. */
255 };
256
257 GNUNET_NETWORK_STRUCT_END
258
259
260 /** 
261  * Handle that identifies a join request.
262  *
263  * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the
264  * corresponding calls to GNUNET_MULTICAST_join_decision().
265  */
266 struct GNUNET_MULTICAST_JoinHandle;
267
268 /** 
269  * Handle that identifies a part request.
270  *
271  * Used to match calls to #GNUNET_MULTICAST_PartCallback to the
272  * corresponding calls to GNUNET_MULTICAST_part_ack().
273  */
274 struct GNUNET_MULTICAST_PartHandle;
275
276
277 /** 
278  * Function to call with the decision made for a join request.
279  *
280  * Must be called once and only once in response to an invocation of the
281  * #GNUNET_MULTICAST_JoinCallback.
282  *
283  * @param jh Join request handle.
284  * @param join_response Message to send in response to the joining peer;
285  *        can also be used to redirect the peer to a different group at the
286  *        application layer; this response is to be transmitted to the
287  *        peer that issued the request even if admission is denied.
288  * @param is_admitted #GNUNET_YES if joining is approved,
289  *        #GNUNET_NO if it is disapproved
290  * @param relay_count Number of relays given.
291  * @param relays Array of suggested peers that might be useful relays to use
292  *        when joining the multicast group (essentially a list of peers that
293  *        are already part of the multicast group and might thus be willing
294  *        to help with routing).  If empty, only this local peer (which must
295  *        be the multicast origin) is a good candidate for building the
296  *        multicast tree.  Note that it is unnecessary to specify our own
297  *        peer identity in this array.
298  */
299 void
300 GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
301                                 const struct GNUNET_MessageHeader *join_response,
302                                 int is_admitted,
303                                 unsigned int relay_count,
304                                 const struct GNUNET_PeerIdentity *relays);
305
306
307 /** 
308  * Part acknowledgment.
309  *
310  * @param ph Part handle.
311  */
312 void
313 GNUNET_MULTICAST_part_ack (struct GNUNET_MULTICAST_PartHandle *ph);
314
315
316 /** 
317  * Method called whenever another peer wants to join the multicast group.
318  *
319  * Implementations of this function must call GNUNET_MULTICAST_join_decision()
320  * with the decision.
321  *
322  * @param cls Closure.
323  * @param peer Identity of the peer that wants to join.
324  * @param msg Application-dependent join message from the new user
325  *        (might, for example, contain a user,
326  *        bind user identity/pseudonym to peer identity, application-level
327  *        message to origin, etc.).
328  * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison().
329  */
330 typedef void (*GNUNET_MULTICAST_JoinCallback)(void *cls,
331                                               const struct GNUNET_PeerIdentity *peer,
332                                               const struct GNUNET_MessageHeader *msg,
333                                               struct GNUNET_MULTICAST_JoinHandle *jh);
334
335
336 /** 
337  * Method called whenever another peer wants to part the multicast group.
338  *
339  * A part request must always be honoured, and answered with GNUNET_MULTICAST_part_ack();
340  *
341  * @param cls Closure.
342  * @param peer Identity of the peer that wants to part.
343  * @param msg Application-dependent part message from the leaving user.
344  * @param ph Part handle.
345  */
346 typedef void (*GNUNET_MULTICAST_PartCallback)(void *cls,
347                                               const struct GNUNET_PeerIdentity *peer,
348                                               const struct GNUNET_MessageHeader *msg,
349                                               struct GNUNET_MULTICAST_PartHandle *ph);
350
351
352 /** 
353  * Handle to pass back for the answer of a membership test.
354  */
355 struct GNUNET_MULTICAST_MembershipTestHandle;
356
357
358 /** 
359  * Call informing multicast about the decision taken for membership test.
360  *
361  * @param mth Handle that was given for the query.
362  * @param decision #GNUNET_YES if peer was a member, #GNUNET_NO if peer was not a member,
363  *         #GNUNET_SYSERR if we cannot answer the membership test.
364  */
365 void
366 GNUNET_MULTICAST_membership_test_answer (struct GNUNET_MULTICAST_MembershipTestHandle *mth,
367                                          int decision);
368
369
370 /** 
371  * Method called to test if a member was in the group at a particular time.
372  *
373  * It is called when a replay request is received to determine if the requested
374  * message can be replayed.
375  *
376  * @param cls Closure.
377  * @param peer Identity of the peer that we want to test.
378  * @param fragment_id Message fragment ID for which we want to do the test.
379  * @param mth Handle to give to GNUNET_MULTICAST_membership_test_answer().
380  */
381 typedef void (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls,
382                                                         const struct GNUNET_PeerIdentity *peer,
383                                                         uint64_t fragment_id,
384                                                         struct GNUNET_MULTICAST_MembershipTestHandle *mth);
385
386
387 /** 
388  * Function called whenever a group member has transmitted a request
389  * to the origin (other than joining or leaving).
390  *
391  * @param cls Closure (set from GNUNET_MULTICAST_origin_start).
392  * @param sender Identity of the sender.
393  * @param req Request to the origin.
394  * @param flags Flags for the request.
395  */
396 typedef void (*GNUNET_MULTICAST_RequestCallback) (void *cls,
397                                                   const struct GNUNET_PeerIdentity *sender,
398                                                   const struct GNUNET_MessageHeader *req,
399                                                   enum GNUNET_MULTICAST_MessageFlags flags);
400
401
402 /** 
403  * Function called whenever a group member is receiving a message fragment from
404  * the origin.
405  *
406  * If admission to the group is denied, this function is called once with the
407  * response of the @e origin (as given to GNUNET_MULTICAST_join_decision()) and
408  * then a second time with NULL to indicate that the connection failed for good.
409  *
410  * @param cls Closure (set from GNUNET_MULTICAST_member_join())
411  * @param msg Message from the origin, NULL if the origin shut down
412  *        (or we were kicked out, and we should thus call
413  *        GNUNET_MULTICAST_member_part() next)
414  */
415 typedef void (*GNUNET_MULTICAST_MessageCallback) (void *cls,
416                                                   const struct GNUNET_MULTICAST_MessageHeader *msg);
417
418
419 /** 
420  * Opaque handle to a replay request from the multicast service.
421  */
422 struct GNUNET_MULTICAST_ReplayHandle;
423
424
425 /** 
426  * Functions with this signature are called whenever the multicast service needs
427  * a message to be replayed.
428  *
429  * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
430  * (with a message or an error); however, if the origin is destroyed or the
431  * group is left, the replay handle must no longer be used.
432  *
433  * @param cls Closure (set from GNUNET_MULTICAST_origin_start()
434  *            or GNUNET_MULTICAST_member_join()).
435  * @param fragment_id Which message fragment should be replayed.
436  * @param rh Handle to pass to message transmit function.
437  */
438 typedef void (*GNUNET_MULTICAST_ReplayCallback) (void *cls,
439                                                  uint64_t fragment_id,
440                                                  struct GNUNET_MULTICAST_ReplayHandle *rh);
441
442
443 /** 
444  * Possible error codes during replay.
445  */
446 enum GNUNET_MULTICAST_ReplayErrorCode
447 {
448
449   /** 
450    * Everything is fine.
451    */
452   GNUNET_MULTICAST_REC_OK = 0,
453
454   /** 
455    * Message fragment has been discarded (likely transient message that was too old).
456    */
457   GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1,
458
459   /** 
460    * Fragment ID counter was larger than the highest counter this
461    * replay function has ever encountered; thus it is likely the
462    * origin never sent it and we're at the HEAD of the multicast
463    * stream as far as this node is concerned.
464    */
465   GNUNET_MULTICAST_REC_PAST_HEAD = 2,
466
467   /** 
468    * Internal error (i.e. database error).  Try some other peer.
469    */
470   GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3
471
472 };
473
474
475 /** 
476  * Replay a message from the multicast group.
477  *
478  * @param rh Replay handle identifying which replay operation was requested.
479  * @param msg Replayed message fragment, NULL if unknown/error.
480  * @param ec Error code.
481  */
482 void
483 GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
484                          const struct GNUNET_MULTICAST_MessageHeader *msg,
485                          enum GNUNET_MULTICAST_ReplayErrorCode ec);
486
487
488 /** 
489  * Start a multicast group.
490  *
491  * Will advertise the origin in the P2P overlay network under the respective
492  * public key so that other peer can find this peer to join it.  Peers that
493  * issue GNUNET_MULTICAST_member_join() can then transmit a join request to
494  * either an existing group member (if the @a join_policy is permissive) or to
495  * the origin.  If the joining is approved, the member is cleared for @e replay
496  * and will begin to receive messages transmitted to the group.  If joining is
497  * disapproved, the failed candidate will be given a response.  Members in the
498  * group can send messages to the origin (one at a time).
499  *
500  * @param cfg Configuration to use.
501  * @param cls Closure for the various callbacks that follow.
502  * @param priv_key ECC key that will be used to sign messages for this
503  *                 multicast session; public key is used to identify the
504  *                 multicast group; FIXME: we'll likely want to use
505  *                 NOT the p521 curve here, but a cheaper one in the future.
506  * @param join_policy What is the membership policy of the group?
507  * @param replay_cb Function that can be called to replay a message.
508  * @param test_cb Function multicast can use to test group membership.
509  * @param join_cb Function called to approve / disapprove joining of a peer.
510  * @param part_cb Function called when a member wants to part the group.
511  * @param request_cb Function called with messages from group members.
512  * @return Handle for the origin, NULL on error.
513  */
514 struct GNUNET_MULTICAST_Origin *
515 GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
516                                void *cls,
517                                const struct GNUNET_CRYPTO_EccPrivateKey *priv_key,
518                                enum GNUNET_MULTICAST_JoinPolicy join_policy,
519                                GNUNET_MULITCAST_ReplayCallback replay_cb,
520                                GNUNET_MULITCAST_MembershipTestCallback test_cb,
521                                GNUNET_MULTICAST_JoinCallback join_cb,
522                                GNUNET_MULTICAST_PartCallback part_cb,
523                                GNUNET_MULTICAST_RequestCallback request_cb);
524
525
526 /** 
527  * Handle for a request to send a message to all multicast group members
528  * (from the origin).
529  */
530 struct GNUNET_MULTICAST_OriginMessageHandle;
531
532
533 /** 
534  * Send a message to the multicast group.
535  *
536  * @param origin Handle to the multicast group.
537  * @param size Number of bytes to transmit.
538  * @param cb Function to call to get the message.
539  * @param cb_cls Closure for @a cb.
540  * @return NULL on error (i.e. request already pending).
541  */
542 struct GNUNET_MULTICAST_OriginMessageHandle *
543 GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
544                                 size_t size,
545                                 GNUNET_CONNECTION_TransmitReadyNotify cb,
546                                 void *cb_cls);
547
548
549 /** 
550  * Cancel request for message transmission to multicast group.
551  *
552  * @param mh Request to cancel.
553  */
554 void
555 GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginMessageHandle *mh);
556
557
558 /** 
559  * Stop a multicast group.
560  *
561  * @param origin Multicast group to stop.
562  */
563 void
564 GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
565
566
567 /** 
568  * Join a multicast group.
569  *
570  * The entity joining is always the local peer.  Further information about the
571  * candidate can be provided in the @a join_req message.  If the join fails, the
572  * @a message_cb is invoked with a (failure) response and then with NULL.  If
573  * the join succeeds, outstanding (state) messages and ongoing multicast
574  * messages will be given to the @a message_cb until the member decides to part
575  * the group.  The @a test_cb and @a replay_cb functions may be called at
576  * anytime by the multicast service to support relaying messages to other
577  * members of the group.
578  *
579  * @param cfg Configuration to use.
580  * @param pub_key ECC key that identifies the group.
581  * @param origin Peer identity of the origin.
582  * @param max_known_fragment_id Largest known message fragment ID to the replay
583           service; all messages with IDs larger than this ID will be replayed if
584  *        possible (lower IDs will be considered known and thus only
585  *        be replayed upon explicit request).
586  * @param max_known_state_fragment_id Largest known message fragment ID with a
587           non-zero value for the @e state_delta; state messages with
588  *        larger IDs than this value will be replayed with high priority
589  *        (lower IDs will be considered known and thus only
590  *        be replayed upon explicit request).
591  * @param replay_cb Function that can be called to replay messages
592  *        this peer already knows from this group; NULL if this
593  *        client is unable to support replay.
594  * @param test_cb Function multicast can use to test group membership.
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  * @param join_req Application-dependent join message to be passed to origin
600  *        (might, for example, contain a user
601  *        bind user identity/pseudonym to peer identity, application-level
602  *        message to origin, etc.).
603  * @return Handle for the member, NULL on error.
604  */
605 struct GNUNET_MULTICAST_Member *
606 GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
607                               const struct GNUNET_CRYPTO_EccPublicKey *pub_key,
608                               const struct GNUNET_PeerIdentity *origin,
609                               uint64_t max_known_fragment_id,
610                               uint64_t max_known_state_fragment_id,
611                               GNUNET_MULTICAST_ReplayCallback replay_cb,
612                               GNUNET_MULITCAST_MembershipTestCallback test_cb,
613                               GNUNET_MULTICAST_MessageCallback message_cb,
614                               void *cls,
615                               const struct GNUNET_MessageHeader *join_req);
616
617
618 /** 
619  * Handle for a replay request.
620  */
621 struct GNUNET_MULTICAST_MemberReplayHandle;
622
623
624 /** 
625  * Request a message to be replayed.
626  *
627  * Useful if messages below the @e max_known_*_id's given when joining are
628  * needed and not known to the client.
629  *
630  * @param member Membership handle.
631  * @param fragment_id ID of a message fragment that this client would like to see replayed.
632  * @param message_cb Function to be called for the replayed message.
633  * @param message_cb_cls Closure for @a message_cb.
634  * @return Replay request handle, NULL on error.
635  */
636 struct GNUNET_MULTICAST_MemberReplayHandle *
637 GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member,
638                                         uint64_t fragment_id,
639                                         GNUNET_MULTICAST_MessageCallback message_cb,
640                                         void *message_cb_cls);
641
642
643 /** 
644  * Cancel a replay request.
645  *
646  * @param rh Request to cancel.
647  */
648 void
649 GNUNET_MULTICAST_member_request_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandle *rh);
650
651
652 /** 
653  * Part a multicast group.
654  *
655  * @param member Membership handle.
656  * @param part_req Application-dependent part request to send to the origin.
657  */
658 void
659 GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member,
660                               const struct GNUNET_MessageHeader *part_req);
661
662
663 /** 
664  * Handle for a message to be delivered from a member to the origin.
665  */
666 struct GNUNET_MULTICAST_MemberRequestHandle;
667
668
669 /** 
670  * Send a message to the origin of the multicast group.
671  * 
672  * @param member Membership handle.
673  * @param size Number of bytes we want to send to origin.
674  * @param cb Callback to call to get the message.
675  * @param cb_cls Closure for @a cb.
676  * @return Handle to cancel request, NULL on error (i.e. request already pending).
677  */
678 struct GNUNET_MULTICAST_MemberRequestHandle *
679 GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
680                                    size_t size,
681                                    GNUNET_CONNECTION_TransmitReadyNotify cb,
682                                    void *cb_cls);
683
684
685 /** 
686  * Cancel request for message transmission to origin.
687  *
688  * @param rh Request to cancel.
689  */
690 void
691 GNUNET_MULTICAST_member_to_origin_cancel (struct GNUNET_MULTICAST_MemberRequestHandle *rh);
692
693
694
695 #if 0                           /* keep Emacsens' auto-indent happy */
696 {
697 #endif
698 #ifdef __cplusplus
699 }
700 #endif
701
702 /* ifndef GNUNET_MULTICAST_SERVICE_H */
703 #endif
704 /* end of gnunet_multicast_service.h */