diff options
author | Gabor X Toth <*@tg-x.net> | 2014-05-17 10:16:15 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2014-05-17 10:16:15 +0000 |
commit | 83c058a5ea11b6d7aa05cb71963c6063cb373603 (patch) | |
tree | 30921098e391d492cf52311983348232d41d9634 /src/multicast | |
parent | d78b7d8a3f6cdaee244557667350da443ca76db5 (diff) | |
download | gnunet-83c058a5ea11b6d7aa05cb71963c6063cb373603.tar.gz gnunet-83c058a5ea11b6d7aa05cb71963c6063cb373603.zip |
multicast, psyc: client connections, join requests
Diffstat (limited to 'src/multicast')
-rw-r--r-- | src/multicast/gnunet-service-multicast.c | 399 | ||||
-rw-r--r-- | src/multicast/multicast.h | 8 | ||||
-rw-r--r-- | src/multicast/multicast_api.c | 99 |
3 files changed, 393 insertions, 113 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c index 0265660e1..0394ee19e 100644 --- a/src/multicast/gnunet-service-multicast.c +++ b/src/multicast/gnunet-service-multicast.c | |||
@@ -46,22 +46,40 @@ static struct GNUNET_SERVER_NotificationContext *nc; | |||
46 | 46 | ||
47 | /** | 47 | /** |
48 | * All connected origins. | 48 | * All connected origins. |
49 | * Group's pub_key_hash -> struct Group | 49 | * Group's pub_key_hash -> struct Origin |
50 | */ | 50 | */ |
51 | static struct GNUNET_CONTAINER_MultiHashMap *origins; | 51 | static struct GNUNET_CONTAINER_MultiHashMap *origins; |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * All connected members. | 54 | * All connected members. |
55 | * Group's pub_key_hash -> struct Group | 55 | * Group's pub_key_hash -> struct Member |
56 | */ | 56 | */ |
57 | static struct GNUNET_CONTAINER_MultiHashMap *members; | 57 | static struct GNUNET_CONTAINER_MultiHashMap *members; |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * Connected members per group. | ||
61 | * Group's pub_key_hash -> Member's pub_key -> struct Member | ||
62 | */ | ||
63 | static struct GNUNET_CONTAINER_MultiHashMap *group_members; | ||
64 | |||
65 | |||
66 | /** | ||
67 | * List of connected clients. | ||
68 | */ | ||
69 | struct ClientList | ||
70 | { | ||
71 | struct ClientList *prev; | ||
72 | struct ClientList *next; | ||
73 | struct GNUNET_SERVER_Client *client; | ||
74 | }; | ||
75 | |||
76 | /** | ||
60 | * Common part of the client context for both an origin and member. | 77 | * Common part of the client context for both an origin and member. |
61 | */ | 78 | */ |
62 | struct Group | 79 | struct Group |
63 | { | 80 | { |
64 | struct GNUNET_SERVER_Client *client; | 81 | struct ClientList *clients_head; |
82 | struct ClientList *clients_tail; | ||
65 | 83 | ||
66 | /** | 84 | /** |
67 | * Public key of the group. | 85 | * Public key of the group. |
@@ -117,6 +135,29 @@ struct Member | |||
117 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; | 135 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; |
118 | 136 | ||
119 | /** | 137 | /** |
138 | * Public key of the member. | ||
139 | */ | ||
140 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | ||
141 | |||
142 | /** | ||
143 | * Hash of @a pub_key. | ||
144 | */ | ||
145 | struct GNUNET_HashCode pub_key_hash; | ||
146 | |||
147 | /** | ||
148 | * Join request sent to the origin / members. | ||
149 | */ | ||
150 | struct GNUNET_MULTICAST_JoinRequest *join_request; | ||
151 | |||
152 | /** | ||
153 | * Join decision sent in reply to our request. | ||
154 | * | ||
155 | * Only a positive decision is stored here, in case of a negative decision the | ||
156 | * client is disconnected. | ||
157 | */ | ||
158 | struct MulticastJoinDecisionMessage *join_decision; | ||
159 | |||
160 | /** | ||
120 | * Last request fragment ID sent to the origin. | 161 | * Last request fragment ID sent to the origin. |
121 | */ | 162 | */ |
122 | uint64_t max_fragment_id; | 163 | uint64_t max_fragment_id; |
@@ -135,23 +176,161 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
135 | /* FIXME: do clean up here */ | 176 | /* FIXME: do clean up here */ |
136 | } | 177 | } |
137 | 178 | ||
179 | /** | ||
180 | * Clean up origin data structures after a client disconnected. | ||
181 | */ | ||
182 | static void | ||
183 | cleanup_origin (struct Origin *orig) | ||
184 | { | ||
185 | struct Group *grp = &orig->grp; | ||
186 | GNUNET_CONTAINER_multihashmap_remove (origins, &grp->pub_key_hash, orig); | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Clean up member data structures after a client disconnected. | ||
192 | */ | ||
193 | static void | ||
194 | cleanup_member (struct Member *mem) | ||
195 | { | ||
196 | struct Group *grp = &mem->grp; | ||
197 | struct GNUNET_CONTAINER_MultiHashMap * | ||
198 | grp_mem = GNUNET_CONTAINER_multihashmap_get (group_members, | ||
199 | &grp->pub_key_hash); | ||
200 | GNUNET_assert (NULL != grp_mem); | ||
201 | GNUNET_CONTAINER_multihashmap_remove (grp_mem, &mem->pub_key_hash, mem); | ||
202 | |||
203 | if (0 == GNUNET_CONTAINER_multihashmap_size (grp_mem)) | ||
204 | { | ||
205 | GNUNET_CONTAINER_multihashmap_remove (group_members, &grp->pub_key_hash, | ||
206 | grp_mem); | ||
207 | GNUNET_CONTAINER_multihashmap_destroy (grp_mem); | ||
208 | } | ||
209 | GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem); | ||
210 | } | ||
211 | |||
212 | |||
213 | /** | ||
214 | * Clean up group data structures after a client disconnected. | ||
215 | */ | ||
216 | static void | ||
217 | cleanup_group (struct Group *grp) | ||
218 | { | ||
219 | (GNUNET_YES == grp->is_origin) | ||
220 | ? cleanup_origin ((struct Origin *) grp) | ||
221 | : cleanup_member ((struct Member *) grp); | ||
222 | |||
223 | GNUNET_free (grp); | ||
224 | } | ||
225 | |||
226 | |||
227 | /** | ||
228 | * Called whenever a client is disconnected. | ||
229 | * | ||
230 | * Frees our resources associated with that client. | ||
231 | * | ||
232 | * @param cls Closure. | ||
233 | * @param client Client handle. | ||
234 | */ | ||
235 | static void | ||
236 | client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | ||
237 | { | ||
238 | if (NULL == client) | ||
239 | return; | ||
240 | |||
241 | struct Group *grp | ||
242 | = GNUNET_SERVER_client_get_user_context (client, struct Group); | ||
243 | |||
244 | if (NULL == grp) | ||
245 | { | ||
246 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
247 | "%p User context is NULL in client_disconnect()\n", grp); | ||
248 | GNUNET_assert (0); | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
253 | "%p Client (%s) disconnected from group %s\n", | ||
254 | grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member", | ||
255 | GNUNET_h2s (&grp->pub_key_hash)); | ||
256 | |||
257 | struct ClientList *cl = grp->clients_head; | ||
258 | while (NULL != cl) | ||
259 | { | ||
260 | if (cl->client == client) | ||
261 | { | ||
262 | GNUNET_CONTAINER_DLL_remove (grp->clients_head, grp->clients_tail, cl); | ||
263 | GNUNET_free (cl); | ||
264 | break; | ||
265 | } | ||
266 | cl = cl->next; | ||
267 | } | ||
268 | |||
269 | if (NULL == grp->clients_head) | ||
270 | { /* Last client disconnected. */ | ||
271 | #if FIXME | ||
272 | if (NULL != grp->tmit_head) | ||
273 | { /* Send pending messages via CADET before cleanup. */ | ||
274 | transmit_message (grp); | ||
275 | } | ||
276 | else | ||
277 | #endif | ||
278 | { | ||
279 | cleanup_group (grp); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
138 | 284 | ||
139 | /** | 285 | /** |
140 | * Iterator callback for sending a message to clients. | 286 | * Send message to all clients connected to the group. |
287 | */ | ||
288 | static void | ||
289 | message_to_clients (const struct Group *grp, | ||
290 | const struct GNUNET_MessageHeader *msg) | ||
291 | { | ||
292 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
293 | "%p Sending message to clients.\n", grp); | ||
294 | |||
295 | struct ClientList *cl = grp->clients_head; | ||
296 | while (NULL != cl) | ||
297 | { | ||
298 | GNUNET_SERVER_notification_context_add (nc, cl->client); | ||
299 | GNUNET_SERVER_notification_context_unicast (nc, cl->client, msg, GNUNET_NO); | ||
300 | cl = cl->next; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | |||
305 | /** | ||
306 | * Iterator callback for sending a message to origin clients. | ||
141 | */ | 307 | */ |
142 | static int | 308 | static int |
143 | message_callback (void *cls, const struct GNUNET_HashCode *pub_key_hash, | 309 | origin_message_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, |
144 | void *group) | 310 | void *origin) |
145 | { | 311 | { |
146 | const struct GNUNET_MessageHeader *msg = cls; | 312 | const struct GNUNET_MessageHeader *msg = cls; |
147 | struct Group *grp = group; | 313 | struct Member *orig = origin; |
148 | 314 | ||
149 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 315 | message_to_clients (&orig->grp, msg); |
150 | "%p Sending message to client.\n", grp); | 316 | return GNUNET_YES; |
317 | } | ||
151 | 318 | ||
152 | GNUNET_SERVER_notification_context_add (nc, grp->client); | ||
153 | GNUNET_SERVER_notification_context_unicast (nc, grp->client, msg, GNUNET_NO); | ||
154 | 319 | ||
320 | /** | ||
321 | * Iterator callback for sending a message to member clients. | ||
322 | */ | ||
323 | static int | ||
324 | member_message_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, | ||
325 | void *member) | ||
326 | { | ||
327 | const struct GNUNET_MessageHeader *msg = cls; | ||
328 | struct Member *mem = member; | ||
329 | |||
330 | if (NULL != mem->join_decision) | ||
331 | { /* Only send message to admitted members */ | ||
332 | message_to_clients (&mem->grp, msg); | ||
333 | } | ||
155 | return GNUNET_YES; | 334 | return GNUNET_YES; |
156 | } | 335 | } |
157 | 336 | ||
@@ -167,10 +346,10 @@ message_to_group (struct Group *grp, const struct GNUNET_MessageHeader *msg) | |||
167 | { | 346 | { |
168 | if (origins != NULL) | 347 | if (origins != NULL) |
169 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, | 348 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, |
170 | message_callback, (void *) msg); | 349 | origin_message_cb, (void *) msg); |
171 | if (members != NULL) | 350 | if (members != NULL) |
172 | GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, | 351 | GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, |
173 | message_callback, (void *) msg); | 352 | member_message_cb, (void *) msg); |
174 | } | 353 | } |
175 | 354 | ||
176 | 355 | ||
@@ -185,7 +364,7 @@ message_to_origin (struct Group *grp, const struct GNUNET_MessageHeader *msg) | |||
185 | { | 364 | { |
186 | if (origins != NULL) | 365 | if (origins != NULL) |
187 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, | 366 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, |
188 | message_callback, (void *) msg); | 367 | origin_message_cb, (void *) msg); |
189 | } | 368 | } |
190 | 369 | ||
191 | 370 | ||
@@ -199,38 +378,47 @@ handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
199 | const struct MulticastOriginStartMessage * | 378 | const struct MulticastOriginStartMessage * |
200 | msg = (const struct MulticastOriginStartMessage *) m; | 379 | msg = (const struct MulticastOriginStartMessage *) m; |
201 | 380 | ||
202 | struct Origin *orig = GNUNET_new (struct Origin); | 381 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; |
203 | orig->priv_key = msg->group_key; | 382 | struct GNUNET_HashCode pub_key_hash; |
204 | 383 | ||
205 | struct Group *grp = &orig->grp; | 384 | GNUNET_CRYPTO_eddsa_key_get_public (&msg->group_key, &pub_key); |
206 | grp->is_origin = GNUNET_YES; | 385 | GNUNET_CRYPTO_hash (&pub_key, sizeof (pub_key), &pub_key_hash); |
207 | grp->client = client; | 386 | |
387 | struct Origin * | ||
388 | orig = GNUNET_CONTAINER_multihashmap_get (origins, &pub_key_hash); | ||
389 | struct Group *grp; | ||
390 | |||
391 | if (NULL == orig) | ||
392 | { | ||
393 | orig = GNUNET_new (struct Origin); | ||
394 | orig->priv_key = msg->group_key; | ||
395 | grp = &orig->grp; | ||
396 | grp->is_origin = GNUNET_YES; | ||
397 | grp->pub_key = pub_key; | ||
398 | grp->pub_key_hash = pub_key_hash; | ||
399 | |||
400 | GNUNET_CONTAINER_multihashmap_put (origins, &grp->pub_key_hash, orig, | ||
401 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
402 | } | ||
403 | else | ||
404 | { | ||
405 | grp = &orig->grp; | ||
406 | } | ||
208 | 407 | ||
209 | GNUNET_CRYPTO_eddsa_key_get_public (&orig->priv_key, &grp->pub_key); | 408 | struct ClientList *cl = GNUNET_new (struct ClientList); |
210 | GNUNET_CRYPTO_hash (&grp->pub_key, sizeof (grp->pub_key), &grp->pub_key_hash); | 409 | cl->client = client; |
410 | GNUNET_CONTAINER_DLL_insert (grp->clients_head, grp->clients_tail, cl); | ||
211 | 411 | ||
212 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 412 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
213 | "%p Client connected as origin to group %s.\n", | 413 | "%p Client connected as origin to group %s.\n", |
214 | orig, GNUNET_h2s (&grp->pub_key_hash)); | 414 | orig, GNUNET_h2s (&grp->pub_key_hash)); |
215 | 415 | ||
216 | GNUNET_SERVER_client_set_user_context (client, grp); | 416 | GNUNET_SERVER_client_set_user_context (client, grp); |
217 | GNUNET_CONTAINER_multihashmap_put (origins, &grp->pub_key_hash, orig, | ||
218 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
219 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 417 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
220 | } | 418 | } |
221 | 419 | ||
222 | 420 | ||
223 | /** | 421 | /** |
224 | * Handle a client stopping an origin. | ||
225 | */ | ||
226 | static void | ||
227 | handle_origin_stop (void *cls, struct GNUNET_SERVER_Client *client, | ||
228 | const struct GNUNET_MessageHeader *msg) | ||
229 | { | ||
230 | } | ||
231 | |||
232 | |||
233 | /** | ||
234 | * Handle a connecting client joining a group. | 422 | * Handle a connecting client joining a group. |
235 | */ | 423 | */ |
236 | static void | 424 | static void |
@@ -240,34 +428,113 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
240 | struct MulticastMemberJoinMessage * | 428 | struct MulticastMemberJoinMessage * |
241 | msg = (struct MulticastMemberJoinMessage *) m; | 429 | msg = (struct MulticastMemberJoinMessage *) m; |
242 | 430 | ||
243 | struct Member *mem = GNUNET_new (struct Member); | 431 | struct GNUNET_CRYPTO_EddsaPublicKey mem_pub_key; |
244 | mem->priv_key = msg->member_key; | 432 | struct GNUNET_HashCode pub_key_hash, mem_pub_key_hash; |
245 | 433 | ||
246 | struct Group *grp = &mem->grp; | 434 | GNUNET_CRYPTO_eddsa_key_get_public (&msg->member_key, &mem_pub_key); |
247 | grp->is_origin = GNUNET_NO; | 435 | GNUNET_CRYPTO_hash (&mem_pub_key, sizeof (mem_pub_key), &mem_pub_key_hash); |
248 | grp->client = client; | 436 | GNUNET_CRYPTO_hash (&msg->group_key, sizeof (msg->group_key), &pub_key_hash); |
249 | grp->pub_key = msg->group_key; | 437 | |
250 | GNUNET_CRYPTO_hash (&grp->pub_key, sizeof (grp->pub_key), &grp->pub_key_hash); | 438 | struct GNUNET_CONTAINER_MultiHashMap * |
439 | grp_mem = GNUNET_CONTAINER_multihashmap_get (group_members, &pub_key_hash); | ||
440 | struct Member *mem = NULL; | ||
441 | struct Group *grp; | ||
442 | |||
443 | if (NULL == grp_mem) | ||
444 | { | ||
445 | grp_mem = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | ||
446 | GNUNET_CONTAINER_multihashmap_put (group_members, &pub_key_hash, grp_mem, | ||
447 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
448 | } | ||
449 | else | ||
450 | { | ||
451 | mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &mem_pub_key_hash); | ||
452 | } | ||
453 | |||
454 | if (NULL == mem) | ||
455 | { | ||
456 | mem = GNUNET_new (struct Member); | ||
457 | mem->priv_key = msg->member_key; | ||
458 | mem->pub_key = mem_pub_key; | ||
459 | mem->pub_key_hash = mem_pub_key_hash; | ||
460 | |||
461 | grp = &mem->grp; | ||
462 | grp->is_origin = GNUNET_NO; | ||
463 | grp->pub_key = msg->group_key; | ||
464 | grp->pub_key_hash = pub_key_hash; | ||
465 | |||
466 | GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem_pub_key_hash, mem, | ||
467 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
468 | GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem, | ||
469 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
470 | } | ||
471 | else | ||
472 | { | ||
473 | grp = &mem->grp; | ||
474 | } | ||
475 | |||
476 | struct ClientList *cl = GNUNET_new (struct ClientList); | ||
477 | cl->client = client; | ||
478 | GNUNET_CONTAINER_DLL_insert (grp->clients_head, grp->clients_tail, cl); | ||
251 | 479 | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 480 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
253 | "%p Client connected as member to group %s.\n", | 481 | "%p Client connected as member to group %s.\n", |
254 | mem, GNUNET_h2s (&grp->pub_key_hash)); | 482 | mem, GNUNET_h2s (&grp->pub_key_hash)); |
255 | 483 | ||
256 | GNUNET_SERVER_client_set_user_context (client, grp); | 484 | GNUNET_SERVER_client_set_user_context (client, grp); |
257 | GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem, | ||
258 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
259 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
260 | } | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Handle a client parting a group. | ||
265 | */ | ||
266 | static void | ||
267 | handle_member_part (void *cls, struct GNUNET_SERVER_Client *client, | ||
268 | const struct GNUNET_MessageHeader *msg) | ||
269 | { | ||
270 | 485 | ||
486 | if (NULL != mem->join_decision) | ||
487 | { /* Already got a join decision, send it to client. */ | ||
488 | GNUNET_SERVER_notification_context_add (nc, client); | ||
489 | GNUNET_SERVER_notification_context_unicast (nc, client, | ||
490 | (struct GNUNET_MessageHeader *) | ||
491 | mem->join_decision, | ||
492 | GNUNET_NO); | ||
493 | } | ||
494 | else if (grp->clients_head == grp->clients_tail) | ||
495 | { /* First client, send join request. */ | ||
496 | struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1]; | ||
497 | uint32_t relay_count = ntohs (msg->relay_count); | ||
498 | struct GNUNET_MessageHeader * | ||
499 | join_req = ((struct GNUNET_MessageHeader *) | ||
500 | ((char *) &msg[1]) + relay_count * sizeof (*relays)); | ||
501 | uint16_t join_req_size = ntohs (join_req->size); | ||
502 | |||
503 | struct MulticastJoinRequestMessage * | ||
504 | req = GNUNET_malloc (sizeof (*req) + join_req_size); | ||
505 | req->header.size = htons (sizeof (*req) + join_req_size); | ||
506 | req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST); | ||
507 | req->group_key = grp->pub_key; | ||
508 | GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key); | ||
509 | memcpy (&req[1], join_req, join_req_size); | ||
510 | |||
511 | req->purpose.size = htonl (sizeof (*req) + join_req_size | ||
512 | - sizeof (req->header) | ||
513 | - sizeof (req->signature)); | ||
514 | req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST); | ||
515 | |||
516 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_sign (&mem->priv_key, &req->purpose, | ||
517 | &req->signature)) | ||
518 | { | ||
519 | /* FIXME: handle error */ | ||
520 | GNUNET_assert (0); | ||
521 | } | ||
522 | |||
523 | if (NULL != mem->join_request) | ||
524 | GNUNET_free (mem->join_request); | ||
525 | mem->join_request = req; | ||
526 | |||
527 | if (GNUNET_YES | ||
528 | == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash)) | ||
529 | { /* Local origin */ | ||
530 | message_to_origin (grp, (struct GNUNET_MessageHeader *) mem->join_request); | ||
531 | } | ||
532 | else | ||
533 | { | ||
534 | /* FIXME: send join request to remote origin / members */ | ||
535 | } | ||
536 | } | ||
537 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
271 | } | 538 | } |
272 | 539 | ||
273 | 540 | ||
@@ -296,7 +563,7 @@ handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, | |||
296 | &msg->signature)) | 563 | &msg->signature)) |
297 | { | 564 | { |
298 | /* FIXME: handle error */ | 565 | /* FIXME: handle error */ |
299 | return; | 566 | GNUNET_assert (0); |
300 | } | 567 | } |
301 | 568 | ||
302 | /* FIXME: send to remote members */ | 569 | /* FIXME: send to remote members */ |
@@ -327,18 +594,24 @@ handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | |||
327 | - sizeof (req->header) | 594 | - sizeof (req->header) |
328 | - sizeof (req->member_key) | 595 | - sizeof (req->member_key) |
329 | - sizeof (req->signature)); | 596 | - sizeof (req->signature)); |
330 | req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE); | 597 | req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST); |
331 | 598 | ||
332 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_sign (&mem->priv_key, &req->purpose, | 599 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_sign (&mem->priv_key, &req->purpose, |
333 | &req->signature)) | 600 | &req->signature)) |
334 | { | 601 | { |
335 | /* FIXME: handle error */ | 602 | /* FIXME: handle error */ |
336 | return; | 603 | GNUNET_assert (0); |
337 | } | 604 | } |
338 | 605 | ||
339 | /* FIXME: send to remote origin */ | 606 | if (GNUNET_YES |
340 | 607 | == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash)) | |
341 | message_to_origin (grp, m); | 608 | { /* Local origin */ |
609 | message_to_origin (grp, m); | ||
610 | } | ||
611 | else | ||
612 | { | ||
613 | /* FIXME: send to remote origin */ | ||
614 | } | ||
342 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 615 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
343 | } | 616 | } |
344 | 617 | ||
@@ -357,15 +630,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
357 | { &handle_origin_start, NULL, | 630 | { &handle_origin_start, NULL, |
358 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, | 631 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, |
359 | 632 | ||
360 | { &handle_origin_stop, NULL, | ||
361 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_STOP, 0 }, | ||
362 | |||
363 | { &handle_member_join, NULL, | 633 | { &handle_member_join, NULL, |
364 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, | 634 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, |
365 | 635 | ||
366 | { &handle_member_part, NULL, | ||
367 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_PART, 0 }, | ||
368 | |||
369 | { &handle_multicast_message, NULL, | 636 | { &handle_multicast_message, NULL, |
370 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, | 637 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, |
371 | 638 | ||
@@ -379,9 +646,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
379 | stats = GNUNET_STATISTICS_create ("multicast", cfg); | 646 | stats = GNUNET_STATISTICS_create ("multicast", cfg); |
380 | origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | 647 | origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); |
381 | members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); | 648 | members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); |
649 | group_members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | ||
382 | nc = GNUNET_SERVER_notification_context_create (server, 1); | 650 | nc = GNUNET_SERVER_notification_context_create (server, 1); |
383 | 651 | ||
384 | GNUNET_SERVER_add_handlers (server, handlers); | 652 | GNUNET_SERVER_add_handlers (server, handlers); |
653 | GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); | ||
385 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, | 654 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, |
386 | NULL); | 655 | NULL); |
387 | } | 656 | } |
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h index daa79e260..5b0fc647c 100644 --- a/src/multicast/multicast.h +++ b/src/multicast/multicast.h | |||
@@ -33,7 +33,7 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
33 | /** | 33 | /** |
34 | * Header of a join request sent to the origin or another member. | 34 | * Header of a join request sent to the origin or another member. |
35 | */ | 35 | */ |
36 | struct GNUNET_MULTICAST_JoinRequest | 36 | struct MulticastJoinRequestMessage |
37 | { | 37 | { |
38 | /** | 38 | /** |
39 | * Header for the join request. | 39 | * Header for the join request. |
@@ -67,7 +67,7 @@ struct GNUNET_MULTICAST_JoinRequest | |||
67 | */ | 67 | */ |
68 | struct GNUNET_PeerIdentity member_peer; | 68 | struct GNUNET_PeerIdentity member_peer; |
69 | 69 | ||
70 | /* Followed by request body. */ | 70 | /* Followed by struct GNUNET_MessageHeader join_request */ |
71 | }; | 71 | }; |
72 | 72 | ||
73 | 73 | ||
@@ -97,9 +97,9 @@ struct MulticastJoinDecisionMessage | |||
97 | */ | 97 | */ |
98 | uint32_t relay_count; | 98 | uint32_t relay_count; |
99 | 99 | ||
100 | /* followed by 'relay_count' peer identities */ | 100 | /* Followed by relay_count peer identities */ |
101 | 101 | ||
102 | /* followed by the join response message */ | 102 | /* Followed by the join response message */ |
103 | 103 | ||
104 | }; | 104 | }; |
105 | 105 | ||
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c index d42f438ae..84dac0545 100644 --- a/src/multicast/multicast_api.c +++ b/src/multicast/multicast_api.c | |||
@@ -196,6 +196,17 @@ struct GNUNET_MULTICAST_Member | |||
196 | */ | 196 | */ |
197 | struct GNUNET_MULTICAST_JoinHandle | 197 | struct GNUNET_MULTICAST_JoinHandle |
198 | { | 198 | { |
199 | struct GNUNET_MULTICAST_Group *group; | ||
200 | |||
201 | /** | ||
202 | * Public key of the joining member. | ||
203 | */ | ||
204 | struct GNUNET_CRYPTO_EddsaPublicKey member_key; | ||
205 | |||
206 | /** | ||
207 | * Peer identity of the joining member. | ||
208 | */ | ||
209 | struct GNUNET_PeerIdentity member_peer; | ||
199 | }; | 210 | }; |
200 | 211 | ||
201 | 212 | ||
@@ -437,8 +448,7 @@ disconnect (void *g) | |||
437 | * Iterator callback for calling message callbacks for all groups. | 448 | * Iterator callback for calling message callbacks for all groups. |
438 | */ | 449 | */ |
439 | static int | 450 | static int |
440 | message_callback (void *cls, const struct GNUNET_HashCode *pub_key_hash, | 451 | message_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, void *group) |
441 | void *group) | ||
442 | { | 452 | { |
443 | const struct GNUNET_MessageHeader *msg = cls; | 453 | const struct GNUNET_MessageHeader *msg = cls; |
444 | struct GNUNET_MULTICAST_Group *grp = group; | 454 | struct GNUNET_MULTICAST_Group *grp = group; |
@@ -456,32 +466,10 @@ message_callback (void *cls, const struct GNUNET_HashCode *pub_key_hash, | |||
456 | 466 | ||
457 | 467 | ||
458 | /** | 468 | /** |
459 | * Handle a multicast message from the service. | ||
460 | * | ||
461 | * Call message callbacks of all origins and members of the destination group. | ||
462 | * | ||
463 | * @param grp Destination group of the message. | ||
464 | * @param msg The message. | ||
465 | */ | ||
466 | static void | ||
467 | handle_multicast_message (struct GNUNET_MULTICAST_Group *grp, | ||
468 | const struct GNUNET_MULTICAST_MessageHeader *msg) | ||
469 | { | ||
470 | if (origins != NULL) | ||
471 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, | ||
472 | message_callback, (void *) msg); | ||
473 | if (members != NULL) | ||
474 | GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, | ||
475 | message_callback, (void *) msg); | ||
476 | } | ||
477 | |||
478 | |||
479 | /** | ||
480 | * Iterator callback for calling request callbacks of origins. | 469 | * Iterator callback for calling request callbacks of origins. |
481 | */ | 470 | */ |
482 | static int | 471 | static int |
483 | request_callback (void *cls, const struct GNUNET_HashCode *chan_key_hash, | 472 | request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, void *origin) |
484 | void *origin) | ||
485 | { | 473 | { |
486 | const struct GNUNET_MULTICAST_RequestHeader *req = cls; | 474 | const struct GNUNET_MULTICAST_RequestHeader *req = cls; |
487 | struct GNUNET_MULTICAST_Origin *orig = origin; | 475 | struct GNUNET_MULTICAST_Origin *orig = origin; |
@@ -497,20 +485,26 @@ request_callback (void *cls, const struct GNUNET_HashCode *chan_key_hash, | |||
497 | 485 | ||
498 | 486 | ||
499 | /** | 487 | /** |
500 | * Handle a multicast request from the service. | 488 | * Iterator callback for calling join request callbacks of origins. |
501 | * | ||
502 | * Call request callbacks of all origins of the destination group. | ||
503 | * | ||
504 | * @param grp Destination group of the message. | ||
505 | * @param msg The message. | ||
506 | */ | 489 | */ |
507 | static void | 490 | static int |
508 | handle_multicast_request (struct GNUNET_MULTICAST_Group *grp, | 491 | join_request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, |
509 | const struct GNUNET_MULTICAST_RequestHeader *req) | 492 | void *group) |
510 | { | 493 | { |
511 | if (NULL != origins) | 494 | const struct MulticastJoinRequestMessage *req = cls; |
512 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, | 495 | struct GNUNET_MULTICAST_Group *grp = group; |
513 | request_callback, (void *) req); | 496 | |
497 | struct GNUNET_MULTICAST_JoinHandle *jh = GNUNET_malloc (sizeof (*jh)); | ||
498 | jh->group = grp; | ||
499 | jh->member_key = req->member_key; | ||
500 | jh->member_peer = req->member_peer; | ||
501 | |||
502 | const struct GNUNET_MessageHeader *msg = NULL; | ||
503 | if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size)) | ||
504 | msg =(const struct GNUNET_MessageHeader *) &req[1]; | ||
505 | |||
506 | grp->join_cb (grp->cb_cls, &req->member_key, msg, jh); | ||
507 | return GNUNET_YES; | ||
514 | } | 508 | } |
515 | 509 | ||
516 | 510 | ||
@@ -551,22 +545,31 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
551 | size_min = sizeof (struct GNUNET_MULTICAST_RequestHeader); | 545 | size_min = sizeof (struct GNUNET_MULTICAST_RequestHeader); |
552 | break; | 546 | break; |
553 | 547 | ||
548 | case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST: | ||
549 | size_min = sizeof (struct MulticastJoinRequestMessage); | ||
550 | break; | ||
551 | |||
554 | default: | 552 | default: |
555 | GNUNET_break_op (0); | 553 | GNUNET_break_op (0); |
556 | return; | 554 | type = 0; |
557 | } | 555 | } |
558 | 556 | ||
559 | if (! ((0 < size_eq && size == size_eq) | 557 | if (! ((0 < size_eq && size == size_eq) |
560 | || (0 < size_min && size_min <= size))) | 558 | || (0 < size_min && size_min <= size))) |
561 | { | 559 | { |
562 | GNUNET_break_op (0); | 560 | GNUNET_break_op (0); |
563 | return; | 561 | type = 0; |
564 | } | 562 | } |
565 | 563 | ||
566 | switch (type) | 564 | switch (type) |
567 | { | 565 | { |
568 | case GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE: | 566 | case GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE: |
569 | handle_multicast_message (grp, (struct GNUNET_MULTICAST_MessageHeader *) msg); | 567 | if (origins != NULL) |
568 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, | ||
569 | message_cb, (void *) msg); | ||
570 | if (members != NULL) | ||
571 | GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, | ||
572 | message_cb, (void *) msg); | ||
570 | break; | 573 | break; |
571 | 574 | ||
572 | case GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST: | 575 | case GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST: |
@@ -576,12 +579,19 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
576 | break; | 579 | break; |
577 | } | 580 | } |
578 | 581 | ||
579 | handle_multicast_request (grp, (struct GNUNET_MULTICAST_RequestHeader *) msg); | 582 | if (NULL != origins) |
583 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, | ||
584 | request_cb, (void *) msg); | ||
580 | break; | 585 | break; |
581 | 586 | ||
582 | default: | 587 | case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST: |
583 | GNUNET_break_op (0); | 588 | if (NULL != origins) |
584 | return; | 589 | GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, |
590 | join_request_cb, (void *) msg); | ||
591 | if (NULL != members) | ||
592 | GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, | ||
593 | join_request_cb, (void *) msg); | ||
594 | break; | ||
585 | } | 595 | } |
586 | 596 | ||
587 | if (NULL != grp->client) | 597 | if (NULL != grp->client) |
@@ -621,6 +631,7 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh, | |||
621 | const struct GNUNET_PeerIdentity *relays, | 631 | const struct GNUNET_PeerIdentity *relays, |
622 | const struct GNUNET_MessageHeader *join_response) | 632 | const struct GNUNET_MessageHeader *join_response) |
623 | { | 633 | { |
634 | GNUNET_free (jh); | ||
624 | return NULL; | 635 | return NULL; |
625 | } | 636 | } |
626 | 637 | ||