diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-02-14 16:08:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-02-14 16:08:23 +0000 |
commit | 53b9610e3c851b38d677e5d820572dbd7ba7ee27 (patch) | |
tree | 3620ee114d3d4b4440af76ecb8b8674a34b6d012 /src/include/gnunet_multicast_service.h | |
parent | b44875024228c5fe2edb24fe4f72e24d4cb94edc (diff) | |
download | gnunet-53b9610e3c851b38d677e5d820572dbd7ba7ee27.tar.gz gnunet-53b9610e3c851b38d677e5d820572dbd7ba7ee27.zip |
-proposed multicast API draft
Diffstat (limited to 'src/include/gnunet_multicast_service.h')
-rw-r--r-- | src/include/gnunet_multicast_service.h | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/src/include/gnunet_multicast_service.h b/src/include/gnunet_multicast_service.h new file mode 100644 index 000000000..58616ef64 --- /dev/null +++ b/src/include/gnunet_multicast_service.h | |||
@@ -0,0 +1,418 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file include/gnunet_multicast_service.h | ||
23 | * @brief multicast service; establish tunnels to distant peers | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #ifndef GNUNET_MULTICAST_SERVICE_H | ||
28 | #define GNUNET_MULTICAST_SERVICE_H | ||
29 | |||
30 | #ifdef __cplusplus | ||
31 | extern "C" | ||
32 | { | ||
33 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
34 | } | ||
35 | #endif | ||
36 | #endif | ||
37 | |||
38 | #include "gnunet_util_lib.h" | ||
39 | #include "gnunet_transport_service.h" | ||
40 | |||
41 | /** | ||
42 | * Version number of GNUnet-multicast API. | ||
43 | */ | ||
44 | #define GNUNET_MULTICAST_VERSION 0x00000000 | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Opaque handle for a multicast group member. | ||
49 | */ | ||
50 | struct GNUNET_MULTICAST_Member; | ||
51 | |||
52 | /** | ||
53 | * Handle for the origin of a multicast group. | ||
54 | */ | ||
55 | struct GNUNET_MULTICAST_Origin; | ||
56 | |||
57 | /** | ||
58 | * Group membership policies. | ||
59 | */ | ||
60 | enum GNUNET_MULTICAST_JoinPolicy | ||
61 | { | ||
62 | /** | ||
63 | * Anyone can join the group, without announcing his presence; all | ||
64 | * messages are always public and can be distributed freely. Joins | ||
65 | * may be announced, but this is not required. | ||
66 | */ | ||
67 | GNUNET_MULTICAST_JP_ANONYMOUS = 0, | ||
68 | |||
69 | /** | ||
70 | * Origin must approve membership to the group, messages must only be | ||
71 | * distributed to current group members. This includes the group | ||
72 | * state as well as transient messages. | ||
73 | */ | ||
74 | GNUNET_MULTICAST_JP_PRIVATE = 1 | ||
75 | |||
76 | #if IDEAS_FOR_FUTURE | ||
77 | /** | ||
78 | * Anyone can freely join the group (no approval required); however, | ||
79 | * transient messages must only be distributed to current group | ||
80 | * members, so the origin must still acknowledge that the member | ||
81 | * joined before transient messages are delivered. As approval is | ||
82 | * guaranteed, the presistent group state can de synchronized freely | ||
83 | * immediately, prior to origin confirmation | ||
84 | */ | ||
85 | GNUNET_MULTICAST_JP_OPEN = 2 | ||
86 | #endif | ||
87 | |||
88 | }; | ||
89 | |||
90 | |||
91 | /** | ||
92 | * Opaque handle to a replay request from the multicast service. | ||
93 | */ | ||
94 | struct GNUNET_MULTICAST_ReplayHandle; | ||
95 | |||
96 | |||
97 | /** | ||
98 | * Functions with this signature are called whenever the multicast | ||
99 | * service needs a message to be replayed. Implementations of this | ||
100 | * function MUST call 'GNUNET_MULTICAST_replay' ONCE (with a message | ||
101 | * or an error); however, if the origin is destroyed or the group is | ||
102 | * left, the replay handle must no longer be used. | ||
103 | * | ||
104 | * @param cls closure (set from GNUNET_MULTICAST_origin_start/join) | ||
105 | * @param message_id which message should be replayed | ||
106 | * @param rh handle to pass to message transmit function | ||
107 | */ | ||
108 | typedef void (*GNUNET_MULTICAST_ReplayCallback) (void *cls, | ||
109 | uint64_t message_id, | ||
110 | struct GNUNET_MULTICAST_ReplayHandle *rh); | ||
111 | |||
112 | |||
113 | /** | ||
114 | * Possible error codes during replay. | ||
115 | */ | ||
116 | enum GNUNET_MULTICAST_ReplayErrorCode | ||
117 | { | ||
118 | |||
119 | /** | ||
120 | * Everything is fine. | ||
121 | */ | ||
122 | GNUNET_MULTICAST_REC_OK = 0, | ||
123 | |||
124 | /** | ||
125 | * Message has been discarded (likely transient message that was too old). | ||
126 | */ | ||
127 | GNUNET_MULTICAST_REC_TRANSIENT_LOST = 1, | ||
128 | |||
129 | /** | ||
130 | * Message ID counter was larger than the highest counter this | ||
131 | * replay function has ever encountered; thus it is likely the | ||
132 | * origin never sent it and we're at the HEAD of the multicast | ||
133 | * stream as far as this node is concerned. | ||
134 | */ | ||
135 | GNUNET_MULTICAST_REC_PAST_HEAD = 2, | ||
136 | |||
137 | /** | ||
138 | * Internal error (i.e. database error). Try some other peer. | ||
139 | */ | ||
140 | GNUNET_MULTICAST_REC_INTERNAL_ERROR = 3 | ||
141 | |||
142 | }; | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Header of a multicast message. This format is public as the replay | ||
147 | * mechanism must replay messages using the same format. | ||
148 | */ | ||
149 | struct GNUNET_MULTICAST_MessageHeader | ||
150 | { | ||
151 | |||
152 | /** | ||
153 | * Header for all multicast messages from the origin. | ||
154 | */ | ||
155 | struct GNUNET_MessageHeader header; | ||
156 | |||
157 | /** | ||
158 | * How many hops has this message taken since the origin? | ||
159 | * (helpful to determine shortest paths to the origin for responses | ||
160 | * among honest peers; updated at each hop and thus not signed | ||
161 | * and not secure) | ||
162 | */ | ||
163 | uint32_t hop_counter; | ||
164 | |||
165 | /** | ||
166 | * ECC signature of the message. | ||
167 | */ | ||
168 | struct GNUNET_CRYPTO_EccSignature signature; | ||
169 | |||
170 | /** | ||
171 | * Signature of the multicast message. | ||
172 | */ | ||
173 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
174 | |||
175 | /** | ||
176 | * Number of the message, monotonically increasing. | ||
177 | */ | ||
178 | uint64_t message_id; | ||
179 | |||
180 | /** | ||
181 | * Counter that monotonically increases whenever a member | ||
182 | * leaves the group. | ||
183 | */ | ||
184 | uint64_t group_generation; | ||
185 | |||
186 | /** | ||
187 | * Difference between the current message_id and the message_id of | ||
188 | * the preceeding non-transient message. Zero for transient | ||
189 | * messages, UINT64_MAX for the first message, or any other message | ||
190 | * creating a full state reset by the origin. By subtracting | ||
191 | * 'state_delta' from 'message_id', it is possible to calculate the | ||
192 | * message ID of the preceeding non-transient message and thus | ||
193 | * quickly traverse all state changes up to the last full state | ||
194 | * reset by the origin. This is useful as it allows joining clients | ||
195 | * to quickly reassemble the state while skipping over transient | ||
196 | * messages (and doing so without having to trust intermediaries to | ||
197 | * do it right, as the indices in the chain are signed). If the | ||
198 | * state chain is getting too long, the origin can choose to | ||
199 | * originate a state message with a state_delta of UINT64_MAX, | ||
200 | * thereby starting a new chain. The origin will then have to | ||
201 | * re-create the full state with state update messages following the | ||
202 | * state reset message. | ||
203 | */ | ||
204 | uint64_t state_delta; | ||
205 | |||
206 | /** | ||
207 | * Header for the message body. Three message types are | ||
208 | * specifically understood by multicast, namely "peer join", "peer | ||
209 | * leave", and "group terminated". Multicast will use those | ||
210 | * messages to update its list of candidates for content | ||
211 | * distribution. All other message types are application-specific. | ||
212 | */ | ||
213 | struct GNUNET_MessageHeader body; | ||
214 | |||
215 | /* followed by message body */ | ||
216 | }; | ||
217 | |||
218 | |||
219 | /** | ||
220 | * Replay a message from the multicast group. | ||
221 | * | ||
222 | * @param rh replay handle identifying which replay operation was requested | ||
223 | * @param msg replayed message, NULL if unknown/error | ||
224 | * @param ec error code | ||
225 | */ | ||
226 | void | ||
227 | GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh, | ||
228 | const struct GNUNET_MULTICAST_MessageHeader *msg, | ||
229 | enum GNUNET_MULTICAST_ReplayErrorCode ec); | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Method called whenever another peer wants to join or has left a | ||
234 | * multicast group. | ||
235 | * | ||
236 | * @param cls closure | ||
237 | * @param peer identity of the peer that wants to join or leave | ||
238 | * @param is_joining GNUNET_YES if the peer wants to join, GNUNET_NO if the peer left | ||
239 | * @return GNUNET_OK if joining is approved, GNUNET_SYSERR if it is disapproved; | ||
240 | * GNUNET_NO should be returned for peers leaving | ||
241 | */ | ||
242 | typedef int (*GNUNET_MULTICAST_MembershipChangeCallback)(void *cls, | ||
243 | const struct GNUNET_PeerIdentity *peer, | ||
244 | int is_joining); | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Method called to test if a member was in the group at a particular time. | ||
249 | * | ||
250 | * @param cls closure | ||
251 | * @param peer identity of the peer that we want to test | ||
252 | * @param message_id message ID for which we want to do the test | ||
253 | * @param group_generation the generation of the group for which we want to do the test | ||
254 | * @return GNUNET_YES if peer was a member, GNUNET_NO if peer was not a member, | ||
255 | * GNUNET_SYSERR if we cannot answer the membership test | ||
256 | */ | ||
257 | typedef int (*GNUNET_MULTICAST_MembershipTestCallback)(void *cls, | ||
258 | const struct GNUNET_PeerIdentity *peer, | ||
259 | uint64_t message_id, | ||
260 | uint64_t group_generation); | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Function called whenever a group member has transmitted a message | ||
265 | * to the origin (other than joining or leaving). | ||
266 | * | ||
267 | * @param cls closure (set from GNUNET_MULTICAST_origin_start) | ||
268 | * @param sender identity of the sender | ||
269 | * @param response_id unique counter for the response from this sender to this origin | ||
270 | * @param msg message to the origin | ||
271 | */ | ||
272 | typedef void (*GNUNET_MULTICAST_ResponseCallback) (void *cls, | ||
273 | const struct GNUNET_PeerIdentity *sender, | ||
274 | uint64_t response_id, | ||
275 | const struct GNUNET_MessageHeader *msg); | ||
276 | |||
277 | |||
278 | /** | ||
279 | * Function called whenever a group member is receiving a message from | ||
280 | * the origin. | ||
281 | * | ||
282 | * @param cls closure (set from GNUNET_MULTICAST_member_join) | ||
283 | * @param msg message from the origin, NULL if the origin shut down | ||
284 | * (or we were kicked out, and we should thus call GNUNET_MULTICAST_member_leave next) | ||
285 | */ | ||
286 | typedef void (*GNUNET_MULTICAST_MessageCallback) (void *cls, | ||
287 | const struct GNUNET_MULTICAST_MessageHeader *msg); | ||
288 | |||
289 | |||
290 | /** | ||
291 | * Start a multicast group. | ||
292 | * | ||
293 | * @param cfg configuration to use | ||
294 | * @param cls closure for the various callbacks that follow | ||
295 | * @param priv_key ECC key that will be used to sign messages for this | ||
296 | * multicast session; public key is used to identify the | ||
297 | * multicast group; FIXME: we'll likely want to use | ||
298 | * NOT the p521 curve here, but a cheaper one in the future | ||
299 | * @param join_policy what is the membership policy of the group? | ||
300 | * @param replay_cb function that can be called to replay a message | ||
301 | * @param test_cb function multicast can use to test group membership | ||
302 | * @param join_cb function called to approve / disapprove joining of a peer | ||
303 | * @param response_cb function called with messages from group members | ||
304 | * @return handle for the origin, NULL on error | ||
305 | */ | ||
306 | struct GNUNET_MULTICAST_Origin * | ||
307 | GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
308 | void *cls, | ||
309 | struct GNUNET_CRYPTO_EccPrivateKey *priv_key, | ||
310 | enum GNUNET_MULTICAST_JoinPolicy join_policy, | ||
311 | GNUNET_MULITCAST_ReplayCallback replay_cb, | ||
312 | GNUNET_MULITCAST_MembershipTestCallback test_cb, | ||
313 | GNUNET_MULTICAST_MembershipChangeCallback join_cb, | ||
314 | GNUNET_MULTICAST_ResponseCallback response_cb); | ||
315 | |||
316 | |||
317 | /** | ||
318 | * Send a message to the multicast group. | ||
319 | * | ||
320 | * @param origin handle to the multicast group | ||
321 | * @param msg_body body of the message to transmit | ||
322 | */ | ||
323 | void | ||
324 | GNUNET_MULTICAST_origin_send_to_all (struct GNUNET_MULTICAST_Origin *origin, | ||
325 | const struct GNUNET_MessageHeader *msg_body); | ||
326 | |||
327 | |||
328 | /** | ||
329 | * End a multicast group. | ||
330 | * | ||
331 | * @param origin multicast group to terminate | ||
332 | */ | ||
333 | void | ||
334 | GNUNET_MULTICAST_origin_end (struct GNUNET_MULTICAST_Origin *origin); | ||
335 | |||
336 | |||
337 | /** | ||
338 | * Join a multicast group. | ||
339 | * | ||
340 | * @param cfg configuration to use | ||
341 | * @param cls closure for callbacks | ||
342 | * @param pub_key ECC key that identifies the group | ||
343 | * @param max_known_message_id largest known message ID to the replay service; | ||
344 | * all messages with IDs larger than this ID will be replayed if | ||
345 | * possible (lower IDs will be considered known and thus only | ||
346 | * be replayed upon explicit request) | ||
347 | * @param max_known_state_message_id largest known message ID with a non-zero | ||
348 | * value for the 'state_delta'; state messages with | ||
349 | * larger IDs than this value will be replayed with high priority | ||
350 | * (lower IDs will be considered known and thus only | ||
351 | * be replayed upon explicit request) | ||
352 | * @param replay_cb function that can be called to replay messages | ||
353 | * this peer already knows from this group; NULL if this | ||
354 | * client is unable to support replay | ||
355 | * @param message_cb function to be called for all messages we | ||
356 | * receive from the group, excluding those our replay_cb | ||
357 | * already has | ||
358 | * FIXME: need some argument(s) to identify the joining member (key pair to | ||
359 | * bind user identity/pseudonym to peer identity, application-level | ||
360 | * message to origin, etc.) | ||
361 | * @return handle for the member, NULL on error | ||
362 | */ | ||
363 | struct GNUNET_MULTICAST_Member * | ||
364 | GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
365 | void *cls, | ||
366 | struct GNUNET_CRYPTO_EccPublicKey *pub_key, | ||
367 | uint64_t max_known_message_id, | ||
368 | uint64_t max_known_state_message_id, | ||
369 | GNUNET_MULTICAST_ReplayCallback replay_cb, | ||
370 | GNUNET_MULTICAST_MessageCallback message_cb); | ||
371 | |||
372 | |||
373 | /** | ||
374 | * Request a message to be replayed. Useful if messages below | ||
375 | * the 'max_known_*_id's given when joining are needed and not | ||
376 | * known to the client. | ||
377 | * | ||
378 | * @param member membership handle | ||
379 | * @param message_id ID of a message that this client would like to see replayed | ||
380 | */ | ||
381 | void | ||
382 | GNUNET_MULTICAST_member_request_replay (struct GNUNET_MULTICAST_Member *member, | ||
383 | uint64_t message_id); | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Leave a mutlicast group. | ||
388 | * | ||
389 | * @param member membership handle | ||
390 | */ | ||
391 | void | ||
392 | GNUNET_MULTICAST_member_leave (struct GNUNET_MULTICAST_Member *member); | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Send a message to the origin of the multicast group. FIXME: how | ||
397 | * will we do routing/flow-control of responses? | ||
398 | * | ||
399 | * @param member membership handle | ||
400 | * @param msg message to send to the origin | ||
401 | * FIXME: change to notify_transmit_ready-style to wait for ACKs... | ||
402 | */ | ||
403 | void | ||
404 | GNUNET_MULTICAST_member_respond_to_origin (struct GNUNET_MULTICAST_Member *member, | ||
405 | const struct GNUNET_MessageHeader *msg); | ||
406 | |||
407 | |||
408 | |||
409 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
410 | { | ||
411 | #endif | ||
412 | #ifdef __cplusplus | ||
413 | } | ||
414 | #endif | ||
415 | |||
416 | /* ifndef GNUNET_MULTICAST_SERVICE_H */ | ||
417 | #endif | ||
418 | /* end of gnunet_multicast_service.h */ | ||