aboutsummaryrefslogtreecommitdiff
path: root/src/multicast
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2014-03-06 23:46:45 +0000
committerGabor X Toth <*@tg-x.net>2014-03-06 23:46:45 +0000
commit8a0b8a4604526e5f832c4971f9c3b1b48d79bea4 (patch)
treedfd18a61272a18381fe9ce9b09849a965480a303 /src/multicast
parenta21beab58c1d2abc747359a98326f19aaad4e8cd (diff)
downloadgnunet-8a0b8a4604526e5f832c4971f9c3b1b48d79bea4.tar.gz
gnunet-8a0b8a4604526e5f832c4971f9c3b1b48d79bea4.zip
PSYC: implement slave to master requests, tests, fixes, reorg
Multicast lib: handle member to origin requests. Keep track of members and origins and call their callbacks when necessary.
Diffstat (limited to 'src/multicast')
-rw-r--r--src/multicast/gnunet-service-multicast.c84
-rw-r--r--src/multicast/multicast.h46
-rw-r--r--src/multicast/multicast_api.c435
3 files changed, 425 insertions, 140 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index f9aa7fe2d..47c8bce36 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -41,6 +41,71 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
41 41
42 42
43/** 43/**
44 * Handle a connecting client starting an origin.
45 */
46static void
47handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client,
48 const struct GNUNET_MessageHeader *msg)
49{
50
51}
52
53
54/**
55 * Handle a client stopping an origin.
56 */
57static void
58handle_origin_stop (void *cls, struct GNUNET_SERVER_Client *client,
59 const struct GNUNET_MessageHeader *msg)
60{
61
62}
63
64
65/**
66 * Handle a connecting client joining a group.
67 */
68static void
69handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
70 const struct GNUNET_MessageHeader *msg)
71{
72
73}
74
75
76/**
77 * Handle a client parting a group.
78 */
79static void
80handle_member_part (void *cls, struct GNUNET_SERVER_Client *client,
81 const struct GNUNET_MessageHeader *msg)
82{
83
84}
85
86
87/**
88 * Incoming message from a client.
89 */
90static void
91handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
92 const struct GNUNET_MessageHeader *msg)
93{
94
95}
96
97
98/**
99 * Incoming request from a client.
100 */
101static void
102handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
103 const struct GNUNET_MessageHeader *msg)
104{
105
106}
107
108/**
44 * Process multicast requests. 109 * Process multicast requests.
45 * 110 *
46 * @param cls closure 111 * @param cls closure
@@ -52,7 +117,24 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
52 const struct GNUNET_CONFIGURATION_Handle *cfg) 117 const struct GNUNET_CONFIGURATION_Handle *cfg)
53{ 118{
54 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 119 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
55 /* FIXME: add handlers here! */ 120 { &handle_origin_start, NULL,
121 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 },
122
123 { &handle_origin_stop, NULL,
124 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_STOP, 0 },
125
126 { &handle_member_join, NULL,
127 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 },
128
129 { &handle_member_part, NULL,
130 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_PART, 0 },
131
132 { &handle_multicast_message, NULL,
133 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
134
135 { &handle_multicast_request, NULL,
136 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 },
137
56 {NULL, NULL, 0, 0} 138 {NULL, NULL, 0, 0}
57 }; 139 };
58 /* FIXME: do setup here */ 140 /* FIXME: do setup here */
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h
index 88cb2d99e..facf8f54e 100644
--- a/src/multicast/multicast.h
+++ b/src/multicast/multicast.h
@@ -22,6 +22,7 @@
22 * @file multicast/multicast.h 22 * @file multicast/multicast.h
23 * @brief multicast IPC messages 23 * @brief multicast IPC messages
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Gabor X Toth
25 */ 26 */
26#ifndef MULTICAST_H 27#ifndef MULTICAST_H
27#define MULTICAST_H 28#define MULTICAST_H
@@ -30,12 +31,52 @@ GNUNET_NETWORK_STRUCT_BEGIN
30 31
31 32
32/** 33/**
34 * Header of a join request sent to the origin or another member.
35 */
36struct GNUNET_MULTICAST_JoinRequest
37{
38 /**
39 * Header for the join request.
40 */
41 struct GNUNET_MessageHeader header;
42
43 /**
44 * ECC signature of the rest of the fields of the join request.
45 *
46 * Signature must match the public key of the joining member.
47 */
48 struct GNUNET_CRYPTO_EddsaSignature signature;
49
50 /**
51 * Purpose for the signature and size of the signed data.
52 */
53 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
54
55 /**
56 * Public key of the target group.
57 */
58 struct GNUNET_CRYPTO_EddsaPublicKey group_key;
59
60 /**
61 * Public key of the joining member.
62 */
63 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
64
65 /**
66 * Peer identity of the joining member.
67 */
68 struct GNUNET_PeerIdentity member_peer;
69
70 /* Followed by request body. */
71};
72
73
74/**
33 * Message sent from the client to the service to notify the service 75 * Message sent from the client to the service to notify the service
34 * about a join decision. 76 * about a join decision.
35 */ 77 */
36struct MulticastJoinDecisionMessage 78struct MulticastJoinDecisionMessage
37{ 79{
38
39 /** 80 /**
40 * 81 *
41 */ 82 */
@@ -329,9 +370,6 @@ struct MulticastUnicastToOriginCancelMessage
329}; 370};
330 371
331 372
332
333
334
335GNUNET_NETWORK_STRUCT_END 373GNUNET_NETWORK_STRUCT_END
336 374
337#endif 375#endif
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index bb6a57b58..25af614af 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -34,6 +34,19 @@
34 34
35 35
36/** 36/**
37 * Started origins.
38 * Group's pub_key_hash -> struct GNUNET_MULTICAST_Origin
39 */
40static struct GNUNET_CONTAINER_MultiHashMap *origins;
41
42/**
43 * Joined members.
44 * group_key_hash -> struct GNUNET_MULTICAST_Member
45 */
46static struct GNUNET_CONTAINER_MultiHashMap *members;
47
48
49/**
37 * Handle for a request to send a message to all multicast group members 50 * Handle for a request to send a message to all multicast group members
38 * (from the origin). 51 * (from the origin).
39 */ 52 */
@@ -49,13 +62,20 @@ struct GNUNET_MULTICAST_OriginMessageHandle
49}; 62};
50 63
51 64
65struct GNUNET_MULTICAST_Group
66{
67 uint8_t is_origin;
68};
69
52/** 70/**
53 * Handle for the origin of a multicast group. 71 * Handle for the origin of a multicast group.
54 */ 72 */
55struct GNUNET_MULTICAST_Origin 73struct GNUNET_MULTICAST_Origin
56{ 74{
57 struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; 75 struct GNUNET_MULTICAST_Group grp;
76
58 struct GNUNET_MULTICAST_OriginMessageHandle msg_handle; 77 struct GNUNET_MULTICAST_OriginMessageHandle msg_handle;
78 struct GNUNET_CRYPTO_EddsaPrivateKey priv_key;
59 79
60 GNUNET_MULTICAST_JoinCallback join_cb; 80 GNUNET_MULTICAST_JoinCallback join_cb;
61 GNUNET_MULTICAST_MembershipTestCallback mem_test_cb; 81 GNUNET_MULTICAST_MembershipTestCallback mem_test_cb;
@@ -66,6 +86,9 @@ struct GNUNET_MULTICAST_Origin
66 void *cls; 86 void *cls;
67 87
68 uint64_t next_fragment_id; 88 uint64_t next_fragment_id;
89
90 struct GNUNET_CRYPTO_EddsaPublicKey pub_key;
91 struct GNUNET_HashCode pub_key_hash;
69}; 92};
70 93
71 94
@@ -74,123 +97,176 @@ struct GNUNET_MULTICAST_Origin
74 */ 97 */
75struct GNUNET_MULTICAST_MemberRequestHandle 98struct GNUNET_MULTICAST_MemberRequestHandle
76{ 99{
100 GNUNET_MULTICAST_MemberTransmitNotify notify;
101 void *notify_cls;
102 struct GNUNET_MULTICAST_Member *member;
103
104 uint64_t request_id;
105 uint64_t fragment_offset;
77}; 106};
78 107
79 108
80/** 109/**
81 * Opaque handle for a multicast group member. 110 * Handle for a multicast group member.
82 */ 111 */
83struct GNUNET_MULTICAST_Member 112struct GNUNET_MULTICAST_Member
84{ 113{
114 struct GNUNET_MULTICAST_Group grp;
115
116 struct GNUNET_MULTICAST_MemberRequestHandle req_handle;
117
118 struct GNUNET_CRYPTO_EddsaPublicKey group_key;
119 struct GNUNET_CRYPTO_EddsaPrivateKey member_key;
120 struct GNUNET_PeerIdentity origin;
121 struct GNUNET_PeerIdentity relays;
122 uint32_t relay_count;
123 struct GNUNET_MessageHeader *join_request;
124 GNUNET_MULTICAST_JoinCallback join_cb;
125 GNUNET_MULTICAST_MembershipTestCallback member_test_cb;
126 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb;
127 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb;
128 GNUNET_MULTICAST_MessageCallback message_cb;
129 void *cls;
130
131 uint64_t next_fragment_id;
132 struct GNUNET_HashCode group_key_hash;
85}; 133};
86 134
87 135
88GNUNET_NETWORK_STRUCT_BEGIN 136/**
137 * Handle that identifies a join request.
138 *
139 * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the
140 * corresponding calls to #GNUNET_MULTICAST_join_decision().
141 */
142struct GNUNET_MULTICAST_JoinHandle
143{
144};
145
89 146
90/** 147/**
91 * Header of a request from a member to the origin. 148 * Handle to pass back for the answer of a membership test.
92 */ 149 */
93struct GNUNET_MULTICAST_RequestHeader 150struct GNUNET_MULTICAST_MembershipTestHandle
94{ 151{
95 /** 152};
96 * Header for all requests from a member to the origin.
97 */
98 struct GNUNET_MessageHeader header;
99 153
100 /**
101 * Public key of the sending member.
102 */
103 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
104 154
105 /** 155/**
106 * ECC signature of the request fragment. 156 * Opaque handle to a replay request from the multicast service.
107 * 157 */
108 * Signature must match the public key of the multicast group. 158struct GNUNET_MULTICAST_ReplayHandle
109 */ 159{
110 struct GNUNET_CRYPTO_EddsaSignature signature; 160};
111 161
112 /**
113 * Purpose for the signature and size of the signed data.
114 */
115 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
116 162
117 /** 163/**
118 * Number of the request fragment, monotonically increasing. 164 * Handle for a replay request.
119 */ 165 */
120 uint64_t fragment_id GNUNET_PACKED; 166struct GNUNET_MULTICAST_MemberReplayHandle
167{
168};
121 169
122 /**
123 * Byte offset of this @e fragment of the @e request.
124 */
125 uint64_t fragment_offset GNUNET_PACKED;
126 170
127 /** 171/**
128 * Number of the request this fragment belongs to. 172 * Iterator callback for calling message callbacks for all groups.
129 * 173 */
130 * Set in GNUNET_MULTICAST_origin_to_all(). 174static int
131 */ 175message_callback (void *cls, const struct GNUNET_HashCode *chan_key_hash,
132 uint64_t request_id GNUNET_PACKED; 176 void *group)
177{
178 const struct GNUNET_MessageHeader *msg = cls;
179 struct GNUNET_MULTICAST_Group *grp = group;
133 180
134 /** 181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
135 * Flags for this request. 182 "Calling message callback for a message of type %u and size %u.\n",
136 */ 183 ntohs (msg->type), ntohs (msg->size));
137 enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED; 184
185 if (GNUNET_YES == grp->is_origin)
186 {
187 struct GNUNET_MULTICAST_Origin *orig = (struct GNUNET_MULTICAST_Origin *) grp;
188 orig->message_cb (orig->cls, msg);
189 }
190 else
191 {
192 struct GNUNET_MULTICAST_Member *mem = (struct GNUNET_MULTICAST_Member *) grp;
193 mem->message_cb (mem->cls, msg);
194 }
195
196 return GNUNET_YES;
197}
138 198
139 /* Followed by request body. */
140};
141 199
142/** 200/**
143 * Header of a join request sent to the origin or another member. 201 * Handle a multicast message from the service.
202 *
203 * Call message callbacks of all origins and members of the destination group.
204 *
205 * @param grp Destination group of the message.
206 * @param msg The message.
144 */ 207 */
145struct GNUNET_MULTICAST_JoinRequest 208static void
209handle_multicast_message (struct GNUNET_MULTICAST_Group *grp,
210 const struct GNUNET_MULTICAST_MessageHeader *msg)
146{ 211{
147 /** 212 struct GNUNET_HashCode *hash;
148 * Header for the join request.
149 */
150 struct GNUNET_MessageHeader header;
151 213
152 /** 214 if (GNUNET_YES == grp->is_origin)
153 * ECC signature of the rest of the fields of the join request. 215 {
154 * 216 struct GNUNET_MULTICAST_Origin *orig = (struct GNUNET_MULTICAST_Origin *) grp;
155 * Signature must match the public key of the joining member. 217 hash = &orig->pub_key_hash;
156 */ 218 }
157 struct GNUNET_CRYPTO_EddsaSignature signature; 219 else
158 220 {
159 /** 221 struct GNUNET_MULTICAST_Member *mem = (struct GNUNET_MULTICAST_Member *) grp;
160 * Purpose for the signature and size of the signed data. 222 hash = &mem->group_key_hash;
161 */ 223 }
162 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
163 224
164 /** 225 if (origins != NULL)
165 * Public key of the target group. 226 GNUNET_CONTAINER_multihashmap_get_multiple (origins, hash, message_callback,
166 */ 227 (void *) msg);
167 struct GNUNET_CRYPTO_EddsaPublicKey group_key; 228 if (members != NULL)
229 GNUNET_CONTAINER_multihashmap_get_multiple (members, hash, message_callback,
230 (void *) msg);
231}
168 232
169 /**
170 * Public key of the joining member.
171 */
172 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
173 233
174 /** 234/**
175 * Peer identity of the joining member. 235 * Iterator callback for calling request callbacks of origins.
176 */ 236 */
177 struct GNUNET_PeerIdentity member_peer; 237static int
238request_callback (void *cls, const struct GNUNET_HashCode *chan_key_hash,
239 void *origin)
240{
241 const struct GNUNET_MULTICAST_RequestHeader *req = cls;
242 struct GNUNET_MULTICAST_Origin *orig = origin;
178 243
179 /* Followed by request body. */ 244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
180}; 245 "Calling request callback for a request of type %u and size %u.\n",
246 ntohs (req->header.type), ntohs (req->header.size));
181 247
182GNUNET_NETWORK_STRUCT_END 248 orig->request_cb (orig->cls, &req->member_key,
249 (const struct GNUNET_MessageHeader *) req, 0);
250 return GNUNET_YES;
251}
183 252
184 253
185/** 254/**
186 * Handle that identifies a join request. 255 * Handle a multicast request from the service.
187 * 256 *
188 * Used to match calls to #GNUNET_MULTICAST_JoinCallback to the 257 * Call request callbacks of all origins of the destination group.
189 * corresponding calls to #GNUNET_MULTICAST_join_decision(). 258 *
259 * @param grp Destination group of the message.
260 * @param msg The message.
190 */ 261 */
191struct GNUNET_MULTICAST_JoinHandle 262static void
263handle_multicast_request (const struct GNUNET_HashCode *group_key_hash,
264 const struct GNUNET_MULTICAST_RequestHeader *req)
192{ 265{
193}; 266 if (NULL != origins)
267 GNUNET_CONTAINER_multihashmap_get_multiple (origins, group_key_hash,
268 request_callback, (void *) req);
269}
194 270
195 271
196/** 272/**
@@ -227,14 +303,6 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
227 303
228 304
229/** 305/**
230 * Handle to pass back for the answer of a membership test.
231 */
232struct GNUNET_MULTICAST_MembershipTestHandle
233{
234};
235
236
237/**
238 * Call informing multicast about the decision taken for a membership test. 306 * Call informing multicast about the decision taken for a membership test.
239 * 307 *
240 * @param mth Handle that was given for the query. 308 * @param mth Handle that was given for the query.
@@ -249,14 +317,6 @@ GNUNET_MULTICAST_membership_test_result (struct GNUNET_MULTICAST_MembershipTestH
249 317
250 318
251/** 319/**
252 * Opaque handle to a replay request from the multicast service.
253 */
254struct GNUNET_MULTICAST_ReplayHandle
255{
256};
257
258
259/**
260 * Replay a message fragment for the multicast group. 320 * Replay a message fragment for the multicast group.
261 * 321 *
262 * @param rh Replay handle identifying which replay operation was requested. 322 * @param rh Replay handle identifying which replay operation was requested.
@@ -340,6 +400,7 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
340 void *cls) 400 void *cls)
341{ 401{
342 struct GNUNET_MULTICAST_Origin *orig = GNUNET_malloc (sizeof (*orig)); 402 struct GNUNET_MULTICAST_Origin *orig = GNUNET_malloc (sizeof (*orig));
403 orig->grp.is_origin = GNUNET_YES;
343 orig->priv_key = *priv_key; 404 orig->priv_key = *priv_key;
344 orig->next_fragment_id = next_fragment_id; 405 orig->next_fragment_id = next_fragment_id;
345 orig->join_cb = join_cb; 406 orig->join_cb = join_cb;
@@ -349,11 +410,38 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
349 orig->request_cb = request_cb; 410 orig->request_cb = request_cb;
350 orig->message_cb = message_cb; 411 orig->message_cb = message_cb;
351 orig->cls = cls; 412 orig->cls = cls;
413
414 GNUNET_CRYPTO_eddsa_key_get_public (&orig->priv_key, &orig->pub_key);
415 GNUNET_CRYPTO_hash (&orig->pub_key, sizeof (orig->pub_key),
416 &orig->pub_key_hash);
417
418 if (NULL == origins)
419 origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
420
421 GNUNET_CONTAINER_multihashmap_put (origins, &orig->pub_key_hash, orig,
422 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
423
424 /* FIXME: send ORIGIN_START to service */
425
352 return orig; 426 return orig;
353} 427}
354 428
355 429
356/* FIXME: for now just send back to the client what it sent. */ 430/**
431 * Stop a multicast group.
432 *
433 * @param origin Multicast group to stop.
434 */
435void
436GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *orig)
437{
438 GNUNET_CONTAINER_multihashmap_remove (origins, &orig->pub_key_hash, orig);
439 GNUNET_free (orig);
440}
441
442
443/* FIXME: for now just call clients' callbacks
444 * without sending anything to multicast. */
357static void 445static void
358schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 446schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
359{ 447{
@@ -371,7 +459,7 @@ schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
371 || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < buf_size) 459 || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < buf_size)
372 { 460 {
373 LOG (GNUNET_ERROR_TYPE_ERROR, 461 LOG (GNUNET_ERROR_TYPE_ERROR,
374 "MasterTransmitNotify() returned error or invalid message size.\n"); 462 "OriginTransmitNotify() returned error or invalid message size.\n");
375 /* FIXME: handle error */ 463 /* FIXME: handle error */
376 return; 464 return;
377 } 465 }
@@ -401,19 +489,18 @@ schedule_origin_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
401 return; 489 return;
402 } 490 }
403 491
404 /* FIXME: send msg to the service and only then call message_cb with the 492 /* FIXME: send msg to the service and only then call handle_multicast_message
405 * returned signed message. 493 * with the returned signed message.
406 * FIXME: Also send to local members in this group.
407 */ 494 */
408 orig->message_cb (orig->cls, (const struct GNUNET_MessageHeader *) msg); 495 handle_multicast_message (&orig->grp, msg);
409 496
410 if (GNUNET_NO == ret) 497 if (GNUNET_NO == ret)
411 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 498 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
412 (GNUNET_TIME_UNIT_SECONDS, 1), 499 (GNUNET_TIME_UNIT_SECONDS, 1),
413 schedule_origin_to_all, orig); 500 schedule_origin_to_all, orig);
414
415} 501}
416 502
503
417/** 504/**
418 * Send a message to the multicast group. 505 * Send a message to the multicast group.
419 * 506 *
@@ -439,6 +526,7 @@ GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
439 mh->notify = notify; 526 mh->notify = notify;
440 mh->notify_cls = notify_cls; 527 mh->notify_cls = notify_cls;
441 528
529 /* FIXME: remove delay, it's there only for testing */
442 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 530 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
443 (GNUNET_TIME_UNIT_SECONDS, 1), 531 (GNUNET_TIME_UNIT_SECONDS, 1),
444 schedule_origin_to_all, origin); 532 schedule_origin_to_all, origin);
@@ -470,18 +558,6 @@ GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginMessageHand
470 558
471 559
472/** 560/**
473 * Stop a multicast group.
474 *
475 * @param origin Multicast group to stop.
476 */
477void
478GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin)
479{
480 GNUNET_free (origin);
481}
482
483
484/**
485 * Join a multicast group. 561 * Join a multicast group.
486 * 562 *
487 * The entity joining is always the local peer. Further information about the 563 * The entity joining is always the local peer. Further information about the
@@ -531,24 +607,61 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
531 const struct GNUNET_PeerIdentity *relays, 607 const struct GNUNET_PeerIdentity *relays,
532 const struct GNUNET_MessageHeader *join_request, 608 const struct GNUNET_MessageHeader *join_request,
533 GNUNET_MULTICAST_JoinCallback join_cb, 609 GNUNET_MULTICAST_JoinCallback join_cb,
534 GNUNET_MULTICAST_MembershipTestCallback mem_test_cb, 610 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
535 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 611 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
536 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 612 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
537 GNUNET_MULTICAST_MessageCallback message_cb, 613 GNUNET_MULTICAST_MessageCallback message_cb,
538 void *cls) 614 void *cls)
539{ 615{
540 struct GNUNET_MULTICAST_Member *mem = GNUNET_malloc (sizeof (*mem)); 616 struct GNUNET_MULTICAST_Member *mem = GNUNET_malloc (sizeof (*mem));
617 mem->group_key = *group_key;
618 mem->member_key = *member_key;
619 mem->origin = *origin;
620 mem->relay_count = relay_count;
621 mem->relays = *relays;
622 mem->join_cb = join_cb;
623 mem->member_test_cb = member_test_cb;
624 mem->replay_frag_cb = replay_frag_cb;
625 mem->message_cb = message_cb;
626 mem->cls = cls;
627
628 if (NULL != join_request)
629 {
630 uint16_t size = ntohs (join_request->size);
631 mem->join_request = GNUNET_malloc (size);
632 memcpy (mem->join_request, join_request, size);
633 }
634
635 GNUNET_CRYPTO_hash (&mem->group_key, sizeof (mem->group_key), &mem->group_key_hash);
636
637 if (NULL == members)
638 members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
639
640 GNUNET_CONTAINER_multihashmap_put (members, &mem->group_key_hash, mem,
641 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
642
643 /* FIXME: send MEMBER_JOIN to service */
541 644
542 return mem; 645 return mem;
543} 646}
544 647
545 648
546/** 649/**
547 * Handle for a replay request. 650 * Part a multicast group.
651 *
652 * Disconnects from all group members and invalidates the @a member handle.
653 *
654 * An application-dependent part message can be transmitted beforehand using
655 * #GNUNET_MULTICAST_member_to_origin())
656 *
657 * @param member Membership handle.
548 */ 658 */
549struct GNUNET_MULTICAST_MemberReplayHandle 659void
660GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *mem)
550{ 661{
551}; 662 GNUNET_CONTAINER_multihashmap_remove (members, &mem->group_key_hash, mem);
663 GNUNET_free (mem);
664}
552 665
553 666
554/** 667/**
@@ -612,20 +725,62 @@ GNUNET_MULTICAST_member_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandl
612} 725}
613 726
614 727
615/** 728/* FIXME: for now just send back to the client what it sent. */
616 * Part a multicast group. 729static void
617 * 730schedule_member_to_origin (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
618 * Disconnects from all group members and invalidates the @a member handle.
619 *
620 * An application-dependent part message can be transmitted beforehand using
621 * #GNUNET_MULTICAST_member_to_origin())
622 *
623 * @param member Membership handle.
624 */
625void
626GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member)
627{ 731{
628 GNUNET_free (member); 732 LOG (GNUNET_ERROR_TYPE_DEBUG, "schedule_member_to_origin()\n");
733 struct GNUNET_MULTICAST_Member *mem = cls;
734 struct GNUNET_MULTICAST_MemberRequestHandle *rh = &mem->req_handle;
735
736 size_t buf_size = GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD;
737 char buf[GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD] = "";
738 struct GNUNET_MULTICAST_RequestHeader *req
739 = (struct GNUNET_MULTICAST_RequestHeader *) buf;
740 int ret = rh->notify (rh->notify_cls, &buf_size, &req[1]);
741
742 if (! (GNUNET_YES == ret || GNUNET_NO == ret)
743 || GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < buf_size)
744 {
745 LOG (GNUNET_ERROR_TYPE_ERROR,
746 "MemberTransmitNotify() returned error or invalid message size.\n");
747 /* FIXME: handle error */
748 return;
749 }
750
751 if (GNUNET_NO == ret && 0 == buf_size)
752 return; /* Transmission paused. */
753
754 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST);
755 req->header.size = htons (sizeof (*req) + buf_size);
756 req->request_id = GNUNET_htonll (rh->request_id);
757
758 /* FIXME: add fragment ID and signature in the service instead of here */
759 req->fragment_id = GNUNET_ntohll (mem->next_fragment_id++);
760 req->fragment_offset = GNUNET_ntohll (rh->fragment_offset);
761 rh->fragment_offset += sizeof (*req) + buf_size;
762 req->purpose.size = htonl (sizeof (*req) + buf_size
763 - sizeof (req->header)
764 - sizeof (req->member_key)
765 - sizeof (req->signature));
766 req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE);
767
768 if (GNUNET_OK != GNUNET_CRYPTO_eddsa_sign (&mem->member_key, &req->purpose,
769 &req->signature))
770 {
771 /* FIXME: handle error */
772 return;
773 }
774
775 /* FIXME: send req to the service and only then call handle_multicast_request
776 * with the returned request.
777 */
778 handle_multicast_request (&mem->group_key_hash, req);
779
780 if (GNUNET_NO == ret)
781 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
782 (GNUNET_TIME_UNIT_SECONDS, 1),
783 schedule_member_to_origin, mem);
629} 784}
630 785
631 786
@@ -633,18 +788,28 @@ GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member)
633 * Send a message to the origin of the multicast group. 788 * Send a message to the origin of the multicast group.
634 * 789 *
635 * @param member Membership handle. 790 * @param member Membership handle.
636 * @param message_id Application layer ID for the message. Opaque to multicast. 791 * @param request_id Application layer ID for the request. Opaque to multicast.
637 * @param notify Callback to call to get the message. 792 * @param notify Callback to call to get the message.
638 * @param notify_cls Closure for @a notify. 793 * @param notify_cls Closure for @a notify.
639 * @return Handle to cancel request, NULL on error (i.e. request already pending). 794 * @return Handle to cancel request, NULL on error (i.e. request already pending).
640 */ 795 */
641struct GNUNET_MULTICAST_MemberRequestHandle * 796struct GNUNET_MULTICAST_MemberRequestHandle *
642GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member, 797GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
643 uint64_t message_id, 798 uint64_t request_id,
644 GNUNET_MULTICAST_MemberTransmitNotify notify, 799 GNUNET_MULTICAST_MemberTransmitNotify notify,
645 void *notify_cls) 800 void *notify_cls)
646{ 801{
647 return NULL; 802 struct GNUNET_MULTICAST_MemberRequestHandle *rh = &member->req_handle;
803 rh->member = member;
804 rh->request_id = request_id;
805 rh->notify = notify;
806 rh->notify_cls = notify_cls;
807
808 /* FIXME: remove delay, it's there only for testing */
809 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
810 (GNUNET_TIME_UNIT_SECONDS, 1),
811 schedule_member_to_origin, member);
812 return &member->req_handle;
648} 813}
649 814
650 815