diff options
author | Gabor X Toth <*@tg-x.net> | 2016-09-23 21:17:15 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2016-09-23 21:17:15 +0000 |
commit | c57d130527529e03bfba65f4f61a4a8baabb0e6e (patch) | |
tree | ea82ec01238ed4430754398dd0c41505937a135e /src/multicast | |
parent | f5e65b30356f20c7fd6f80fc1a9cb6de8e035505 (diff) | |
download | gnunet-c57d130527529e03bfba65f4f61a4a8baabb0e6e.tar.gz gnunet-c57d130527529e03bfba65f4f61a4a8baabb0e6e.zip |
multicast: switch to SERVICE API
Diffstat (limited to 'src/multicast')
-rw-r--r-- | src/multicast/gnunet-service-multicast.c | 601 |
1 files changed, 344 insertions, 257 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c index 5f8b1cdb6..75e98eae3 100644 --- a/src/multicast/gnunet-service-multicast.c +++ b/src/multicast/gnunet-service-multicast.c | |||
@@ -38,9 +38,9 @@ | |||
38 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 38 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * Server handle. | 41 | * Service handle. |
42 | */ | 42 | */ |
43 | static struct GNUNET_SERVER_Handle *server; | 43 | static struct GNUNET_SERVICE_Handle *service; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * CADET handle. | 46 | * CADET handle. |
@@ -58,11 +58,6 @@ static struct GNUNET_PeerIdentity this_peer; | |||
58 | static struct GNUNET_STATISTICS_Handle *stats; | 58 | static struct GNUNET_STATISTICS_Handle *stats; |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * Notification context, simplifies client broadcasts. | ||
62 | */ | ||
63 | static struct GNUNET_SERVER_NotificationContext *nc; | ||
64 | |||
65 | /** | ||
66 | * All connected origin clients. | 61 | * All connected origin clients. |
67 | * Group's pub_key_hash -> struct Origin * (uniq) | 62 | * Group's pub_key_hash -> struct Origin * (uniq) |
68 | */ | 63 | */ |
@@ -102,7 +97,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *replay_req_cadet; | |||
102 | /** | 97 | /** |
103 | * Incoming replay requests from clients. | 98 | * Incoming replay requests from clients. |
104 | * Group's pub_key_hash -> | 99 | * Group's pub_key_hash -> |
105 | * H(fragment_id, message_id, fragment_offset, flags) -> struct GNUNET_SERVER_Client * | 100 | * H(fragment_id, message_id, fragment_offset, flags) -> struct GNUNET_SERVICE_Client * |
106 | */ | 101 | */ |
107 | static struct GNUNET_CONTAINER_MultiHashMap *replay_req_client; | 102 | static struct GNUNET_CONTAINER_MultiHashMap *replay_req_client; |
108 | 103 | ||
@@ -135,7 +130,7 @@ struct Channel | |||
135 | * | 130 | * |
136 | * Only set for outgoing channels. | 131 | * Only set for outgoing channels. |
137 | */ | 132 | */ |
138 | struct Group *grp; | 133 | struct Group *group; |
139 | 134 | ||
140 | /** | 135 | /** |
141 | * CADET channel. | 136 | * CADET channel. |
@@ -193,11 +188,12 @@ struct ClientList | |||
193 | { | 188 | { |
194 | struct ClientList *prev; | 189 | struct ClientList *prev; |
195 | struct ClientList *next; | 190 | struct ClientList *next; |
196 | struct GNUNET_SERVER_Client *client; | 191 | struct GNUNET_SERVICE_Client *client; |
197 | }; | 192 | }; |
198 | 193 | ||
194 | |||
199 | /** | 195 | /** |
200 | * Common part of the client context for both an origin and member. | 196 | * Client context for an origin or member. |
201 | */ | 197 | */ |
202 | struct Group | 198 | struct Group |
203 | { | 199 | { |
@@ -220,23 +216,28 @@ struct Group | |||
220 | struct GNUNET_HashCode cadet_port_hash; | 216 | struct GNUNET_HashCode cadet_port_hash; |
221 | 217 | ||
222 | /** | 218 | /** |
223 | * Is this an origin (#GNUNET_YES), or member (#GNUNET_NO)? | 219 | * Is the client disconnected? #GNUNET_YES or #GNUNET_NO |
224 | */ | 220 | */ |
225 | uint8_t is_origin; | 221 | uint8_t disconnected; |
226 | 222 | ||
227 | /** | 223 | /** |
228 | * Is the client disconnected? #GNUNET_YES or #GNUNET_NO | 224 | * Is this an origin (#GNUNET_YES), or member (#GNUNET_NO)? |
229 | */ | 225 | */ |
230 | uint8_t disconnected; | 226 | uint8_t is_origin; |
227 | |||
228 | union { | ||
229 | struct Origin *origin; | ||
230 | struct Member *member; | ||
231 | }; | ||
231 | }; | 232 | }; |
232 | 233 | ||
233 | 234 | ||
234 | /** | 235 | /** |
235 | * Client context for a group's origin. | 236 | * Client context for a group's origin. |
236 | */ | 237 | */ |
237 | struct Origin | 238 | struct Origin |
238 | { | 239 | { |
239 | struct Group grp; | 240 | struct Group group; |
240 | 241 | ||
241 | /** | 242 | /** |
242 | * Private key of the group. | 243 | * Private key of the group. |
@@ -260,7 +261,7 @@ struct Origin | |||
260 | */ | 261 | */ |
261 | struct Member | 262 | struct Member |
262 | { | 263 | { |
263 | struct Group grp; | 264 | struct Group group; |
264 | 265 | ||
265 | /** | 266 | /** |
266 | * Private key of the member. | 267 | * Private key of the member. |
@@ -317,6 +318,15 @@ struct Member | |||
317 | }; | 318 | }; |
318 | 319 | ||
319 | 320 | ||
321 | /** | ||
322 | * Client context. | ||
323 | */ | ||
324 | struct Client { | ||
325 | struct GNUNET_SERVICE_Client *client; | ||
326 | struct Group *group; | ||
327 | }; | ||
328 | |||
329 | |||
320 | struct ReplayRequestKey | 330 | struct ReplayRequestKey |
321 | { | 331 | { |
322 | uint64_t fragment_id; | 332 | uint64_t fragment_id; |
@@ -354,7 +364,7 @@ shutdown_task (void *cls) | |||
354 | static void | 364 | static void |
355 | cleanup_origin (struct Origin *orig) | 365 | cleanup_origin (struct Origin *orig) |
356 | { | 366 | { |
357 | struct Group *grp = &orig->grp; | 367 | struct Group *grp = &orig->group; |
358 | GNUNET_CONTAINER_multihashmap_remove (origins, &grp->pub_key_hash, orig); | 368 | GNUNET_CONTAINER_multihashmap_remove (origins, &grp->pub_key_hash, orig); |
359 | if (NULL != orig->cadet_port) | 369 | if (NULL != orig->cadet_port) |
360 | { | 370 | { |
@@ -371,7 +381,7 @@ cleanup_origin (struct Origin *orig) | |||
371 | static void | 381 | static void |
372 | cleanup_member (struct Member *mem) | 382 | cleanup_member (struct Member *mem) |
373 | { | 383 | { |
374 | struct Group *grp = &mem->grp; | 384 | struct Group *grp = &mem->group; |
375 | struct GNUNET_CONTAINER_MultiHashMap * | 385 | struct GNUNET_CONTAINER_MultiHashMap * |
376 | grp_mem = GNUNET_CONTAINER_multihashmap_get (group_members, | 386 | grp_mem = GNUNET_CONTAINER_multihashmap_get (group_members, |
377 | &grp->pub_key_hash); | 387 | &grp->pub_key_hash); |
@@ -401,8 +411,8 @@ static void | |||
401 | cleanup_group (struct Group *grp) | 411 | cleanup_group (struct Group *grp) |
402 | { | 412 | { |
403 | (GNUNET_YES == grp->is_origin) | 413 | (GNUNET_YES == grp->is_origin) |
404 | ? cleanup_origin ((struct Origin *) grp) | 414 | ? cleanup_origin (grp->origin) |
405 | : cleanup_member ((struct Member *) grp); | 415 | : cleanup_member (grp->member); |
406 | } | 416 | } |
407 | 417 | ||
408 | 418 | ||
@@ -435,7 +445,7 @@ replay_req_remove_cadet (struct Channel *chn) | |||
435 | { | 445 | { |
436 | struct GNUNET_CONTAINER_MultiHashMap * | 446 | struct GNUNET_CONTAINER_MultiHashMap * |
437 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, | 447 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, |
438 | &chn->grp->pub_key_hash); | 448 | &chn->group->pub_key_hash); |
439 | if (NULL == grp_replay_req) | 449 | if (NULL == grp_replay_req) |
440 | return GNUNET_NO; | 450 | return GNUNET_NO; |
441 | 451 | ||
@@ -469,7 +479,7 @@ replay_req_remove_cadet (struct Channel *chn) | |||
469 | * #GNUNET_NO when reached end of hashmap. | 479 | * #GNUNET_NO when reached end of hashmap. |
470 | */ | 480 | */ |
471 | static int | 481 | static int |
472 | replay_req_remove_client (struct Group *grp, struct GNUNET_SERVER_Client *client) | 482 | replay_req_remove_client (struct Group *grp, struct GNUNET_SERVICE_Client *client) |
473 | { | 483 | { |
474 | struct GNUNET_CONTAINER_MultiHashMap * | 484 | struct GNUNET_CONTAINER_MultiHashMap * |
475 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_client, | 485 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_client, |
@@ -480,7 +490,7 @@ replay_req_remove_client (struct Group *grp, struct GNUNET_SERVER_Client *client | |||
480 | struct GNUNET_CONTAINER_MultiHashMapIterator * | 490 | struct GNUNET_CONTAINER_MultiHashMapIterator * |
481 | it = GNUNET_CONTAINER_multihashmap_iterator_create (grp_replay_req); | 491 | it = GNUNET_CONTAINER_multihashmap_iterator_create (grp_replay_req); |
482 | struct GNUNET_HashCode key; | 492 | struct GNUNET_HashCode key; |
483 | const struct GNUNET_SERVER_Client *c; | 493 | const struct GNUNET_SERVICE_Client *c; |
484 | while (GNUNET_YES | 494 | while (GNUNET_YES |
485 | == GNUNET_CONTAINER_multihashmap_iterator_next (it, &key, | 495 | == GNUNET_CONTAINER_multihashmap_iterator_next (it, &key, |
486 | (const void **) &c)) | 496 | (const void **) &c)) |
@@ -498,77 +508,20 @@ replay_req_remove_client (struct Group *grp, struct GNUNET_SERVER_Client *client | |||
498 | 508 | ||
499 | 509 | ||
500 | /** | 510 | /** |
501 | * Called whenever a client is disconnected. | ||
502 | * | ||
503 | * Frees our resources associated with that client. | ||
504 | * | ||
505 | * @param cls Closure. | ||
506 | * @param client Client handle. | ||
507 | */ | ||
508 | static void | ||
509 | client_notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | ||
510 | { | ||
511 | if (NULL == client) | ||
512 | return; | ||
513 | |||
514 | struct Group *grp | ||
515 | = GNUNET_SERVER_client_get_user_context (client, struct Group); | ||
516 | |||
517 | if (NULL == grp) | ||
518 | { | ||
519 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
520 | "%p User context is NULL in client_disconnect()\n", grp); | ||
521 | GNUNET_break (0); | ||
522 | return; | ||
523 | } | ||
524 | |||
525 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
526 | "%p Client (%s) disconnected from group %s\n", | ||
527 | grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member", | ||
528 | GNUNET_h2s (&grp->pub_key_hash)); | ||
529 | |||
530 | struct ClientList *cl = grp->clients_head; | ||
531 | while (NULL != cl) | ||
532 | { | ||
533 | if (cl->client == client) | ||
534 | { | ||
535 | GNUNET_CONTAINER_DLL_remove (grp->clients_head, grp->clients_tail, cl); | ||
536 | GNUNET_free (cl); | ||
537 | break; | ||
538 | } | ||
539 | cl = cl->next; | ||
540 | } | ||
541 | |||
542 | while (GNUNET_YES == replay_req_remove_client (grp, client)); | ||
543 | |||
544 | if (NULL == grp->clients_head) | ||
545 | { /* Last client disconnected. */ | ||
546 | #if FIXME | ||
547 | if (NULL != grp->tmit_head) | ||
548 | { /* Send pending messages via CADET before cleanup. */ | ||
549 | transmit_message (grp); | ||
550 | } | ||
551 | else | ||
552 | #endif | ||
553 | { | ||
554 | cleanup_group (grp); | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | |||
559 | |||
560 | /** | ||
561 | * Send message to a client. | 511 | * Send message to a client. |
562 | */ | 512 | */ |
563 | static void | 513 | static void |
564 | client_send (struct GNUNET_SERVER_Client *client, | 514 | client_send (struct GNUNET_SERVICE_Client *client, |
565 | const struct GNUNET_MessageHeader *msg) | 515 | const struct GNUNET_MessageHeader *msg) |
566 | { | 516 | { |
567 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 517 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
568 | "%p Sending message to client.\n", client); | 518 | "%p Sending message to client.\n", client); |
569 | 519 | ||
570 | GNUNET_SERVER_notification_context_add (nc, client); | 520 | struct GNUNET_MQ_Envelope * |
571 | GNUNET_SERVER_notification_context_unicast (nc, client, msg, GNUNET_NO); | 521 | env = GNUNET_MQ_msg_copy (msg); |
522 | |||
523 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), | ||
524 | env); | ||
572 | } | 525 | } |
573 | 526 | ||
574 | 527 | ||
@@ -585,8 +538,11 @@ client_send_group (const struct Group *grp, | |||
585 | struct ClientList *cl = grp->clients_head; | 538 | struct ClientList *cl = grp->clients_head; |
586 | while (NULL != cl) | 539 | while (NULL != cl) |
587 | { | 540 | { |
588 | GNUNET_SERVER_notification_context_add (nc, cl->client); | 541 | struct GNUNET_MQ_Envelope * |
589 | GNUNET_SERVER_notification_context_unicast (nc, cl->client, msg, GNUNET_NO); | 542 | env = GNUNET_MQ_msg_copy (msg); |
543 | |||
544 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cl->client), | ||
545 | env); | ||
590 | cl = cl->next; | 546 | cl = cl->next; |
591 | } | 547 | } |
592 | } | 548 | } |
@@ -602,7 +558,7 @@ client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, | |||
602 | const struct GNUNET_MessageHeader *msg = cls; | 558 | const struct GNUNET_MessageHeader *msg = cls; |
603 | struct Member *orig = origin; | 559 | struct Member *orig = origin; |
604 | 560 | ||
605 | client_send_group (&orig->grp, msg); | 561 | client_send_group (&orig->group, msg); |
606 | return GNUNET_YES; | 562 | return GNUNET_YES; |
607 | } | 563 | } |
608 | 564 | ||
@@ -619,7 +575,7 @@ client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, | |||
619 | 575 | ||
620 | if (NULL != mem->join_dcsn) | 576 | if (NULL != mem->join_dcsn) |
621 | { /* Only send message to admitted members */ | 577 | { /* Only send message to admitted members */ |
622 | client_send_group (&mem->grp, msg); | 578 | client_send_group (&mem->group, msg); |
623 | } | 579 | } |
624 | return GNUNET_YES; | 580 | return GNUNET_YES; |
625 | } | 581 | } |
@@ -785,7 +741,7 @@ static struct Channel * | |||
785 | cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer) | 741 | cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer) |
786 | { | 742 | { |
787 | struct Channel *chn = GNUNET_malloc (sizeof (*chn)); | 743 | struct Channel *chn = GNUNET_malloc (sizeof (*chn)); |
788 | chn->grp = grp; | 744 | chn->group = grp; |
789 | chn->group_pub_key = grp->pub_key; | 745 | chn->group_pub_key = grp->pub_key; |
790 | chn->group_pub_hash = grp->pub_key_hash; | 746 | chn->group_pub_hash = grp->pub_key_hash; |
791 | chn->peer = *peer; | 747 | chn->peer = *peer; |
@@ -806,14 +762,14 @@ cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer) | |||
806 | static void | 762 | static void |
807 | cadet_send_join_request (struct Member *mem) | 763 | cadet_send_join_request (struct Member *mem) |
808 | { | 764 | { |
809 | mem->origin_channel = cadet_channel_create (&mem->grp, &mem->origin); | 765 | mem->origin_channel = cadet_channel_create (&mem->group, &mem->origin); |
810 | cadet_send_channel (mem->origin_channel, &mem->join_req->header); | 766 | cadet_send_channel (mem->origin_channel, &mem->join_req->header); |
811 | 767 | ||
812 | uint32_t i; | 768 | uint32_t i; |
813 | for (i = 0; i < mem->relay_count; i++) | 769 | for (i = 0; i < mem->relay_count; i++) |
814 | { | 770 | { |
815 | struct Channel * | 771 | struct Channel * |
816 | chn = cadet_channel_create (&mem->grp, &mem->relays[i]); | 772 | chn = cadet_channel_create (&mem->group, &mem->relays[i]); |
817 | cadet_send_channel (chn, &mem->join_req->header); | 773 | cadet_send_channel (chn, &mem->join_req->header); |
818 | } | 774 | } |
819 | } | 775 | } |
@@ -923,11 +879,11 @@ cadet_notify_channel_end (void *cls, | |||
923 | return; | 879 | return; |
924 | 880 | ||
925 | struct Channel *chn = ctx; | 881 | struct Channel *chn = ctx; |
926 | if (NULL != chn->grp) | 882 | if (NULL != chn->group) |
927 | { | 883 | { |
928 | if (GNUNET_NO == chn->grp->is_origin) | 884 | if (GNUNET_NO == chn->group->is_origin) |
929 | { | 885 | { |
930 | struct Member *mem = (struct Member *) chn->grp; | 886 | struct Member *mem = (struct Member *) chn->group; |
931 | if (chn == mem->origin_channel) | 887 | if (chn == mem->origin_channel) |
932 | mem->origin_channel = NULL; | 888 | mem->origin_channel = NULL; |
933 | } | 889 | } |
@@ -957,11 +913,11 @@ group_set_cadet_port_hash (struct Group *grp) | |||
957 | * Handle a connecting client starting an origin. | 913 | * Handle a connecting client starting an origin. |
958 | */ | 914 | */ |
959 | static void | 915 | static void |
960 | client_recv_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | 916 | handle_client_origin_start (void *cls, |
961 | const struct GNUNET_MessageHeader *m) | 917 | const struct MulticastOriginStartMessage *msg) |
962 | { | 918 | { |
963 | const struct MulticastOriginStartMessage * | 919 | struct Client *c = cls; |
964 | msg = (const struct MulticastOriginStartMessage *) m; | 920 | struct GNUNET_SERVICE_Client *client = c->client; |
965 | 921 | ||
966 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; | 922 | struct GNUNET_CRYPTO_EddsaPublicKey pub_key; |
967 | struct GNUNET_HashCode pub_key_hash; | 923 | struct GNUNET_HashCode pub_key_hash; |
@@ -978,7 +934,9 @@ client_recv_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
978 | orig = GNUNET_new (struct Origin); | 934 | orig = GNUNET_new (struct Origin); |
979 | orig->priv_key = msg->group_key; | 935 | orig->priv_key = msg->group_key; |
980 | orig->max_fragment_id = GNUNET_ntohll (msg->max_fragment_id); | 936 | orig->max_fragment_id = GNUNET_ntohll (msg->max_fragment_id); |
981 | grp = &orig->grp; | 937 | |
938 | grp = c->group = &orig->group; | ||
939 | grp->origin = orig; | ||
982 | grp->is_origin = GNUNET_YES; | 940 | grp->is_origin = GNUNET_YES; |
983 | grp->pub_key = pub_key; | 941 | grp->pub_key = pub_key; |
984 | grp->pub_key_hash = pub_key_hash; | 942 | grp->pub_key_hash = pub_key_hash; |
@@ -992,7 +950,7 @@ client_recv_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
992 | } | 950 | } |
993 | else | 951 | else |
994 | { | 952 | { |
995 | grp = &orig->grp; | 953 | grp = &orig->group; |
996 | } | 954 | } |
997 | 955 | ||
998 | struct ClientList *cl = GNUNET_new (struct ClientList); | 956 | struct ClientList *cl = GNUNET_new (struct ClientList); |
@@ -1002,9 +960,31 @@ client_recv_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
1002 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 960 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1003 | "%p Client connected as origin to group %s.\n", | 961 | "%p Client connected as origin to group %s.\n", |
1004 | orig, GNUNET_h2s (&grp->pub_key_hash)); | 962 | orig, GNUNET_h2s (&grp->pub_key_hash)); |
963 | GNUNET_SERVICE_client_continue (client); | ||
964 | } | ||
965 | |||
1005 | 966 | ||
1006 | GNUNET_SERVER_client_set_user_context (client, grp); | 967 | static int |
1007 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 968 | check_client_member_join (void *cls, |
969 | const struct MulticastMemberJoinMessage *msg) | ||
970 | { | ||
971 | uint16_t msg_size = ntohs (msg->header.size); | ||
972 | struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1]; | ||
973 | uint32_t relay_count = ntohl (msg->relay_count); | ||
974 | uint16_t relay_size = relay_count * sizeof (*relays); | ||
975 | struct GNUNET_MessageHeader *join_msg = NULL; | ||
976 | uint16_t join_msg_size = 0; | ||
977 | if (sizeof (*msg) + relay_size + sizeof (struct GNUNET_MessageHeader) | ||
978 | <= msg_size) | ||
979 | { | ||
980 | join_msg = (struct GNUNET_MessageHeader *) | ||
981 | (((char *) &msg[1]) + relay_size); | ||
982 | join_msg_size = ntohs (join_msg->size); | ||
983 | } | ||
984 | return | ||
985 | msg_size == (sizeof (*msg) + relay_size + join_msg_size) | ||
986 | ? GNUNET_OK | ||
987 | : GNUNET_SYSERR; | ||
1008 | } | 988 | } |
1009 | 989 | ||
1010 | 990 | ||
@@ -1012,11 +992,12 @@ client_recv_origin_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
1012 | * Handle a connecting client joining a group. | 992 | * Handle a connecting client joining a group. |
1013 | */ | 993 | */ |
1014 | static void | 994 | static void |
1015 | client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, | 995 | handle_client_member_join (void *cls, |
1016 | const struct GNUNET_MessageHeader *m) | 996 | const struct MulticastMemberJoinMessage *msg) |
1017 | { | 997 | { |
1018 | const struct MulticastMemberJoinMessage * | 998 | struct Client *c = cls; |
1019 | msg = (const struct MulticastMemberJoinMessage *) m; | 999 | struct GNUNET_SERVICE_Client *client = c->client; |
1000 | |||
1020 | uint16_t msg_size = ntohs (msg->header.size); | 1001 | uint16_t msg_size = ntohs (msg->header.size); |
1021 | 1002 | ||
1022 | struct GNUNET_CRYPTO_EcdsaPublicKey mem_pub_key; | 1003 | struct GNUNET_CRYPTO_EcdsaPublicKey mem_pub_key; |
@@ -1043,7 +1024,8 @@ client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1043 | mem->pub_key_hash = mem_pub_key_hash; | 1024 | mem->pub_key_hash = mem_pub_key_hash; |
1044 | mem->max_fragment_id = 0; // FIXME | 1025 | mem->max_fragment_id = 0; // FIXME |
1045 | 1026 | ||
1046 | grp = &mem->grp; | 1027 | grp = c->group = &mem->group; |
1028 | grp->member = mem; | ||
1047 | grp->is_origin = GNUNET_NO; | 1029 | grp->is_origin = GNUNET_NO; |
1048 | grp->pub_key = msg->group_pub_key; | 1030 | grp->pub_key = msg->group_pub_key; |
1049 | grp->pub_key_hash = pub_key_hash; | 1031 | grp->pub_key_hash = pub_key_hash; |
@@ -1062,7 +1044,7 @@ client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1062 | } | 1044 | } |
1063 | else | 1045 | else |
1064 | { | 1046 | { |
1065 | grp = &mem->grp; | 1047 | grp = &mem->group; |
1066 | } | 1048 | } |
1067 | 1049 | ||
1068 | struct ClientList *cl = GNUNET_new (struct ClientList); | 1050 | struct ClientList *cl = GNUNET_new (struct ClientList); |
@@ -1078,15 +1060,13 @@ client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1078 | mem, GNUNET_h2s (&mem->pub_key_hash), str); | 1060 | mem, GNUNET_h2s (&mem->pub_key_hash), str); |
1079 | GNUNET_free (str); | 1061 | GNUNET_free (str); |
1080 | 1062 | ||
1081 | GNUNET_SERVER_client_set_user_context (client, grp); | ||
1082 | |||
1083 | if (NULL != mem->join_dcsn) | 1063 | if (NULL != mem->join_dcsn) |
1084 | { /* Already got a join decision, send it to client. */ | 1064 | { /* Already got a join decision, send it to client. */ |
1085 | GNUNET_SERVER_notification_context_add (nc, client); | 1065 | struct GNUNET_MQ_Envelope * |
1086 | GNUNET_SERVER_notification_context_unicast (nc, client, | 1066 | env = GNUNET_MQ_msg_copy (&mem->join_dcsn->header); |
1087 | (struct GNUNET_MessageHeader *) | 1067 | |
1088 | mem->join_dcsn, | 1068 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), |
1089 | GNUNET_NO); | 1069 | env); |
1090 | } | 1070 | } |
1091 | else | 1071 | else |
1092 | { /* First client of the group, send join request. */ | 1072 | { /* First client of the group, send join request. */ |
@@ -1102,12 +1082,6 @@ client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1102 | (((char *) &msg[1]) + relay_size); | 1082 | (((char *) &msg[1]) + relay_size); |
1103 | join_msg_size = ntohs (join_msg->size); | 1083 | join_msg_size = ntohs (join_msg->size); |
1104 | } | 1084 | } |
1105 | if (sizeof (*msg) + relay_size + join_msg_size != msg_size) | ||
1106 | { | ||
1107 | GNUNET_break (0); | ||
1108 | GNUNET_SERVER_client_disconnect (client); | ||
1109 | return; | ||
1110 | } | ||
1111 | 1085 | ||
1112 | struct MulticastJoinRequestMessage * | 1086 | struct MulticastJoinRequestMessage * |
1113 | req = GNUNET_malloc (sizeof (*req) + join_msg_size); | 1087 | req = GNUNET_malloc (sizeof (*req) + join_msg_size); |
@@ -1142,7 +1116,7 @@ client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, | |||
1142 | cadet_send_join_request (mem); | 1116 | cadet_send_join_request (mem); |
1143 | } | 1117 | } |
1144 | } | 1118 | } |
1145 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1119 | GNUNET_SERVICE_client_continue (client); |
1146 | } | 1120 | } |
1147 | 1121 | ||
1148 | 1122 | ||
@@ -1150,7 +1124,7 @@ static void | |||
1150 | client_send_join_decision (struct Member *mem, | 1124 | client_send_join_decision (struct Member *mem, |
1151 | const struct MulticastJoinDecisionMessageHeader *hdcsn) | 1125 | const struct MulticastJoinDecisionMessageHeader *hdcsn) |
1152 | { | 1126 | { |
1153 | client_send_group (&mem->grp, &hdcsn->header); | 1127 | client_send_group (&mem->group, &hdcsn->header); |
1154 | 1128 | ||
1155 | const struct MulticastJoinDecisionMessage * | 1129 | const struct MulticastJoinDecisionMessage * |
1156 | dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; | 1130 | dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; |
@@ -1166,22 +1140,29 @@ client_send_join_decision (struct Member *mem, | |||
1166 | } | 1140 | } |
1167 | 1141 | ||
1168 | 1142 | ||
1143 | static int | ||
1144 | check_client_join_decision (void *cls, | ||
1145 | const struct MulticastJoinDecisionMessageHeader *hdcsn) | ||
1146 | { | ||
1147 | return GNUNET_OK; | ||
1148 | } | ||
1149 | |||
1150 | |||
1169 | /** | 1151 | /** |
1170 | * Join decision from client. | 1152 | * Join decision from client. |
1171 | */ | 1153 | */ |
1172 | static void | 1154 | static void |
1173 | client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, | 1155 | handle_client_join_decision (void *cls, |
1174 | const struct GNUNET_MessageHeader *m) | 1156 | const struct MulticastJoinDecisionMessageHeader *hdcsn) |
1175 | { | 1157 | { |
1176 | struct Group * | 1158 | struct Client *c = cls; |
1177 | grp = GNUNET_SERVER_client_get_user_context (client, struct Group); | 1159 | struct GNUNET_SERVICE_Client *client = c->client; |
1178 | const struct MulticastJoinDecisionMessageHeader * | 1160 | struct Group *grp = c->group; |
1179 | hdcsn = (const struct MulticastJoinDecisionMessageHeader *) m; | ||
1180 | 1161 | ||
1181 | if (NULL == grp) | 1162 | if (NULL == grp) |
1182 | { | 1163 | { |
1183 | GNUNET_break (0); | 1164 | GNUNET_break (0); |
1184 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1165 | GNUNET_SERVICE_client_drop (client); |
1185 | return; | 1166 | return; |
1186 | } | 1167 | } |
1187 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1168 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1210,7 +1191,15 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, | |||
1210 | { /* Look for remote member */ | 1191 | { /* Look for remote member */ |
1211 | cadet_send_join_decision (grp, hdcsn); | 1192 | cadet_send_join_decision (grp, hdcsn); |
1212 | } | 1193 | } |
1213 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1194 | GNUNET_SERVICE_client_continue (client); |
1195 | } | ||
1196 | |||
1197 | |||
1198 | static int | ||
1199 | check_client_multicast_message (void *cls, | ||
1200 | const struct GNUNET_MULTICAST_MessageHeader *msg) | ||
1201 | { | ||
1202 | return GNUNET_OK; | ||
1214 | } | 1203 | } |
1215 | 1204 | ||
1216 | 1205 | ||
@@ -1218,25 +1207,25 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, | |||
1218 | * Incoming message from a client. | 1207 | * Incoming message from a client. |
1219 | */ | 1208 | */ |
1220 | static void | 1209 | static void |
1221 | client_recv_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, | 1210 | handle_client_multicast_message (void *cls, |
1222 | const struct GNUNET_MessageHeader *m) | 1211 | const struct GNUNET_MULTICAST_MessageHeader *msg) |
1223 | { | 1212 | { |
1224 | struct Group * | 1213 | struct Client *c = cls; |
1225 | grp = GNUNET_SERVER_client_get_user_context (client, struct Group); | 1214 | struct GNUNET_SERVICE_Client *client = c->client; |
1226 | struct GNUNET_MULTICAST_MessageHeader *out; | 1215 | struct Group *grp = c->group; |
1227 | struct Origin *orig; | ||
1228 | 1216 | ||
1229 | if (NULL == grp) | 1217 | if (NULL == grp) |
1230 | { | 1218 | { |
1231 | GNUNET_break (0); | 1219 | GNUNET_break (0); |
1232 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1220 | GNUNET_SERVICE_client_drop (client); |
1233 | return; | 1221 | return; |
1234 | } | 1222 | } |
1235 | GNUNET_assert (GNUNET_YES == grp->is_origin); | 1223 | GNUNET_assert (GNUNET_YES == grp->is_origin); |
1236 | orig = (struct Origin *) grp; | 1224 | struct Origin *orig = grp->origin; |
1237 | 1225 | ||
1238 | /* FIXME: yucky, should use separate message structs for P2P and CS! */ | 1226 | /* FIXME: yucky, should use separate message structs for P2P and CS! */ |
1239 | out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (m); | 1227 | struct GNUNET_MULTICAST_MessageHeader * |
1228 | out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (&msg->header); | ||
1240 | out->fragment_id = GNUNET_htonll (++orig->max_fragment_id); | 1229 | out->fragment_id = GNUNET_htonll (++orig->max_fragment_id); |
1241 | out->purpose.size = htonl (ntohs (out->header.size) | 1230 | out->purpose.size = htonl (ntohs (out->header.size) |
1242 | - sizeof (out->header) | 1231 | - sizeof (out->header) |
@@ -1257,7 +1246,15 @@ client_recv_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, | |||
1257 | } | 1246 | } |
1258 | GNUNET_free (out); | 1247 | GNUNET_free (out); |
1259 | 1248 | ||
1260 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1249 | GNUNET_SERVICE_client_continue (client); |
1250 | } | ||
1251 | |||
1252 | |||
1253 | static int | ||
1254 | check_client_multicast_request (void *cls, | ||
1255 | const struct GNUNET_MULTICAST_RequestHeader *req) | ||
1256 | { | ||
1257 | return GNUNET_OK; | ||
1261 | } | 1258 | } |
1262 | 1259 | ||
1263 | 1260 | ||
@@ -1265,23 +1262,25 @@ client_recv_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, | |||
1265 | * Incoming request from a client. | 1262 | * Incoming request from a client. |
1266 | */ | 1263 | */ |
1267 | static void | 1264 | static void |
1268 | client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | 1265 | handle_client_multicast_request (void *cls, |
1269 | const struct GNUNET_MessageHeader *m) | 1266 | const struct GNUNET_MULTICAST_RequestHeader *req) |
1270 | { | 1267 | { |
1271 | struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group); | 1268 | struct Client *c = cls; |
1272 | struct Member *mem; | 1269 | struct GNUNET_SERVICE_Client *client = c->client; |
1273 | struct GNUNET_MULTICAST_RequestHeader *out; | 1270 | struct Group *grp = c->group; |
1271 | |||
1274 | if (NULL == grp) | 1272 | if (NULL == grp) |
1275 | { | 1273 | { |
1276 | GNUNET_break (0); | 1274 | GNUNET_break (0); |
1277 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1275 | GNUNET_SERVICE_client_drop (client); |
1278 | return; | 1276 | return; |
1279 | } | 1277 | } |
1280 | GNUNET_assert (GNUNET_NO == grp->is_origin); | 1278 | GNUNET_assert (GNUNET_NO == grp->is_origin); |
1281 | mem = (struct Member *) grp; | 1279 | struct Member *mem = grp->member; |
1282 | 1280 | ||
1283 | /* FIXME: yucky, should use separate message structs for P2P and CS! */ | 1281 | /* FIXME: yucky, should use separate message structs for P2P and CS! */ |
1284 | out = (struct GNUNET_MULTICAST_RequestHeader *) GNUNET_copy_message (m); | 1282 | struct GNUNET_MULTICAST_RequestHeader * |
1283 | out = (struct GNUNET_MULTICAST_RequestHeader *) GNUNET_copy_message (&req->header); | ||
1285 | out->member_pub_key = mem->pub_key; | 1284 | out->member_pub_key = mem->pub_key; |
1286 | out->fragment_id = GNUNET_ntohll (++mem->max_fragment_id); | 1285 | out->fragment_id = GNUNET_ntohll (++mem->max_fragment_id); |
1287 | out->purpose.size = htonl (ntohs (out->header.size) | 1286 | out->purpose.size = htonl (ntohs (out->header.size) |
@@ -1307,7 +1306,7 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | |||
1307 | else | 1306 | else |
1308 | { | 1307 | { |
1309 | /* FIXME: not yet connected to origin */ | 1308 | /* FIXME: not yet connected to origin */ |
1310 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1309 | GNUNET_SERVICE_client_drop (client); |
1311 | GNUNET_free (out); | 1310 | GNUNET_free (out); |
1312 | return; | 1311 | return; |
1313 | } | 1312 | } |
@@ -1317,7 +1316,7 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | |||
1317 | client_send_ack (&grp->pub_key_hash); | 1316 | client_send_ack (&grp->pub_key_hash); |
1318 | } | 1317 | } |
1319 | GNUNET_free (out); | 1318 | GNUNET_free (out); |
1320 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1319 | GNUNET_SERVICE_client_continue (client); |
1321 | } | 1320 | } |
1322 | 1321 | ||
1323 | 1322 | ||
@@ -1325,19 +1324,21 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, | |||
1325 | * Incoming replay request from a client. | 1324 | * Incoming replay request from a client. |
1326 | */ | 1325 | */ |
1327 | static void | 1326 | static void |
1328 | client_recv_replay_request (void *cls, struct GNUNET_SERVER_Client *client, | 1327 | handle_client_replay_request (void *cls, |
1329 | const struct GNUNET_MessageHeader *m) | 1328 | const struct MulticastReplayRequestMessage *rep) |
1330 | { | 1329 | { |
1331 | struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group); | 1330 | struct Client *c = cls; |
1332 | struct Member *mem; | 1331 | struct GNUNET_SERVICE_Client *client = c->client; |
1332 | struct Group *grp = c->group; | ||
1333 | |||
1333 | if (NULL == grp) | 1334 | if (NULL == grp) |
1334 | { | 1335 | { |
1335 | GNUNET_break (0); | 1336 | GNUNET_break (0); |
1336 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1337 | GNUNET_SERVICE_client_drop (client); |
1337 | return; | 1338 | return; |
1338 | } | 1339 | } |
1339 | GNUNET_assert (GNUNET_NO == grp->is_origin); | 1340 | GNUNET_assert (GNUNET_NO == grp->is_origin); |
1340 | mem = (struct Member *) grp; | 1341 | struct Member *mem = grp->member; |
1341 | 1342 | ||
1342 | struct GNUNET_CONTAINER_MultiHashMap * | 1343 | struct GNUNET_CONTAINER_MultiHashMap * |
1343 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_client, | 1344 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_client, |
@@ -1349,28 +1350,27 @@ client_recv_replay_request (void *cls, struct GNUNET_SERVER_Client *client, | |||
1349 | &grp->pub_key_hash, grp_replay_req, | 1350 | &grp->pub_key_hash, grp_replay_req, |
1350 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 1351 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
1351 | } | 1352 | } |
1352 | struct MulticastReplayRequestMessage * | 1353 | |
1353 | rep = (struct MulticastReplayRequestMessage *) m; | ||
1354 | struct GNUNET_HashCode key_hash; | 1354 | struct GNUNET_HashCode key_hash; |
1355 | replay_key_hash (rep->fragment_id, rep->message_id, rep->fragment_offset, | 1355 | replay_key_hash (rep->fragment_id, rep->message_id, rep->fragment_offset, |
1356 | rep->flags, &key_hash); | 1356 | rep->flags, &key_hash); |
1357 | GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client, | 1357 | GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client, |
1358 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 1358 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
1359 | 1359 | ||
1360 | if (0 == client_send_origin (&grp->pub_key_hash, m)) | 1360 | if (0 == client_send_origin (&grp->pub_key_hash, &rep->header)) |
1361 | { /* No local origin, replay from remote members / origin. */ | 1361 | { /* No local origin, replay from remote members / origin. */ |
1362 | if (NULL != mem->origin_channel) | 1362 | if (NULL != mem->origin_channel) |
1363 | { | 1363 | { |
1364 | cadet_send_channel (mem->origin_channel, m); | 1364 | cadet_send_channel (mem->origin_channel, &rep->header); |
1365 | } | 1365 | } |
1366 | else | 1366 | else |
1367 | { | 1367 | { |
1368 | /* FIXME: not yet connected to origin */ | 1368 | /* FIXME: not yet connected to origin */ |
1369 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1369 | GNUNET_SERVICE_client_drop (client); |
1370 | return; | 1370 | return; |
1371 | } | 1371 | } |
1372 | } | 1372 | } |
1373 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1373 | GNUNET_SERVICE_client_continue (client); |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | 1376 | ||
@@ -1392,7 +1392,7 @@ client_send_replay_response_cb (void *cls, | |||
1392 | const struct GNUNET_HashCode *key_hash, | 1392 | const struct GNUNET_HashCode *key_hash, |
1393 | void *value) | 1393 | void *value) |
1394 | { | 1394 | { |
1395 | struct GNUNET_SERVER_Client *client = value; | 1395 | struct GNUNET_SERVICE_Client *client = value; |
1396 | struct GNUNET_MessageHeader *msg = cls; | 1396 | struct GNUNET_MessageHeader *msg = cls; |
1397 | 1397 | ||
1398 | client_send (client, msg); | 1398 | client_send (client, msg); |
@@ -1400,31 +1400,39 @@ client_send_replay_response_cb (void *cls, | |||
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | 1402 | ||
1403 | static int | ||
1404 | check_client_replay_response_end (void *cls, | ||
1405 | const struct MulticastReplayResponseMessage *res) | ||
1406 | { | ||
1407 | return GNUNET_OK; | ||
1408 | } | ||
1409 | |||
1410 | |||
1403 | /** | 1411 | /** |
1404 | * End of replay response from a client. | 1412 | * End of replay response from a client. |
1405 | */ | 1413 | */ |
1406 | static void | 1414 | static void |
1407 | client_recv_replay_response_end (void *cls, struct GNUNET_SERVER_Client *client, | 1415 | handle_client_replay_response_end (void *cls, |
1408 | const struct GNUNET_MessageHeader *m) | 1416 | const struct MulticastReplayResponseMessage *res) |
1409 | { | 1417 | { |
1410 | struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group); | 1418 | struct Client *c = cls; |
1419 | struct GNUNET_SERVICE_Client *client = c->client; | ||
1420 | struct Group *grp = c->group; | ||
1421 | |||
1411 | if (NULL == grp) | 1422 | if (NULL == grp) |
1412 | { | 1423 | { |
1413 | GNUNET_break (0); | 1424 | GNUNET_break (0); |
1414 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1425 | GNUNET_SERVICE_client_drop (client); |
1415 | return; | 1426 | return; |
1416 | } | 1427 | } |
1417 | 1428 | ||
1418 | struct MulticastReplayResponseMessage * | ||
1419 | res = (struct MulticastReplayResponseMessage *) m; | ||
1420 | |||
1421 | struct GNUNET_HashCode key_hash; | 1429 | struct GNUNET_HashCode key_hash; |
1422 | replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset, | 1430 | replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset, |
1423 | res->flags, &key_hash); | 1431 | res->flags, &key_hash); |
1424 | 1432 | ||
1425 | struct GNUNET_CONTAINER_MultiHashMap * | 1433 | struct GNUNET_CONTAINER_MultiHashMap * |
1426 | grp_replay_req_cadet = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, | 1434 | grp_replay_req_cadet = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, |
1427 | &grp->pub_key_hash); | 1435 | &grp->pub_key_hash); |
1428 | if (NULL != grp_replay_req_cadet) | 1436 | if (NULL != grp_replay_req_cadet) |
1429 | { | 1437 | { |
1430 | GNUNET_CONTAINER_multihashmap_remove_all (grp_replay_req_cadet, &key_hash); | 1438 | GNUNET_CONTAINER_multihashmap_remove_all (grp_replay_req_cadet, &key_hash); |
@@ -1436,7 +1444,24 @@ client_recv_replay_response_end (void *cls, struct GNUNET_SERVER_Client *client, | |||
1436 | { | 1444 | { |
1437 | GNUNET_CONTAINER_multihashmap_remove_all (grp_replay_req_client, &key_hash); | 1445 | GNUNET_CONTAINER_multihashmap_remove_all (grp_replay_req_client, &key_hash); |
1438 | } | 1446 | } |
1439 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1447 | GNUNET_SERVICE_client_continue (client); |
1448 | } | ||
1449 | |||
1450 | |||
1451 | static int | ||
1452 | check_client_replay_response (void *cls, | ||
1453 | const struct MulticastReplayResponseMessage *res) | ||
1454 | { | ||
1455 | const struct GNUNET_MessageHeader *msg = &res->header; | ||
1456 | if (GNUNET_MULTICAST_REC_OK == res->error_code) | ||
1457 | { | ||
1458 | msg = GNUNET_MQ_extract_nested_mh (res); | ||
1459 | if (NULL == msg) | ||
1460 | { | ||
1461 | return GNUNET_SYSERR; | ||
1462 | } | ||
1463 | } | ||
1464 | return GNUNET_OK; | ||
1440 | } | 1465 | } |
1441 | 1466 | ||
1442 | 1467 | ||
@@ -1446,24 +1471,24 @@ client_recv_replay_response_end (void *cls, struct GNUNET_SERVER_Client *client, | |||
1446 | * Respond with a multicast message on success, or otherwise with an error code. | 1471 | * Respond with a multicast message on success, or otherwise with an error code. |
1447 | */ | 1472 | */ |
1448 | static void | 1473 | static void |
1449 | client_recv_replay_response (void *cls, struct GNUNET_SERVER_Client *client, | 1474 | handle_client_replay_response (void *cls, |
1450 | const struct GNUNET_MessageHeader *m) | 1475 | const struct MulticastReplayResponseMessage *res) |
1451 | { | 1476 | { |
1452 | struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group); | 1477 | struct Client *c = cls; |
1478 | struct GNUNET_SERVICE_Client *client = c->client; | ||
1479 | struct Group *grp = c->group; | ||
1480 | |||
1453 | if (NULL == grp) | 1481 | if (NULL == grp) |
1454 | { | 1482 | { |
1455 | GNUNET_break (0); | 1483 | GNUNET_break (0); |
1456 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1484 | GNUNET_SERVICE_client_drop (client); |
1457 | return; | 1485 | return; |
1458 | } | 1486 | } |
1459 | 1487 | ||
1460 | struct MulticastReplayResponseMessage * | 1488 | const struct GNUNET_MessageHeader *msg = &res->header; |
1461 | res = (struct MulticastReplayResponseMessage *) m; | ||
1462 | |||
1463 | const struct GNUNET_MessageHeader *msg = m; | ||
1464 | if (GNUNET_MULTICAST_REC_OK == res->error_code) | 1489 | if (GNUNET_MULTICAST_REC_OK == res->error_code) |
1465 | { | 1490 | { |
1466 | msg = (struct GNUNET_MessageHeader *) &res[1]; | 1491 | msg = GNUNET_MQ_extract_nested_mh (res); |
1467 | } | 1492 | } |
1468 | 1493 | ||
1469 | struct GNUNET_HashCode key_hash; | 1494 | struct GNUNET_HashCode key_hash; |
@@ -1493,57 +1518,14 @@ client_recv_replay_response (void *cls, struct GNUNET_SERVER_Client *client, | |||
1493 | } | 1518 | } |
1494 | else | 1519 | else |
1495 | { | 1520 | { |
1496 | client_recv_replay_response_end (cls, client, m); | 1521 | handle_client_replay_response_end (c, res); |
1497 | return; | 1522 | return; |
1498 | } | 1523 | } |
1499 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1524 | GNUNET_SERVICE_client_continue (client); |
1500 | } | ||
1501 | |||
1502 | |||
1503 | /** | ||
1504 | * A new client connected. | ||
1505 | */ | ||
1506 | static void | ||
1507 | client_notify_connect (void *cls, struct GNUNET_SERVER_Client *client) | ||
1508 | { | ||
1509 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client); | ||
1510 | /* FIXME: send connect ACK */ | ||
1511 | } | 1525 | } |
1512 | 1526 | ||
1513 | 1527 | ||
1514 | /** | 1528 | /** |
1515 | * Message handlers for the server. | ||
1516 | */ | ||
1517 | static const struct GNUNET_SERVER_MessageHandler server_handlers[] = { | ||
1518 | { client_recv_origin_start, NULL, | ||
1519 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, | ||
1520 | |||
1521 | { client_recv_member_join, NULL, | ||
1522 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, | ||
1523 | |||
1524 | { client_recv_join_decision, NULL, | ||
1525 | GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 }, | ||
1526 | |||
1527 | { client_recv_multicast_message, NULL, | ||
1528 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, | ||
1529 | |||
1530 | { client_recv_multicast_request, NULL, | ||
1531 | GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, | ||
1532 | |||
1533 | { client_recv_replay_request, NULL, | ||
1534 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 0 }, | ||
1535 | |||
1536 | { client_recv_replay_response, NULL, | ||
1537 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 0 }, | ||
1538 | |||
1539 | { client_recv_replay_response_end, NULL, | ||
1540 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END, 0 }, | ||
1541 | |||
1542 | { NULL, NULL, 0, 0 } | ||
1543 | }; | ||
1544 | |||
1545 | |||
1546 | /** | ||
1547 | * Incoming join request message from CADET. | 1529 | * Incoming join request message from CADET. |
1548 | */ | 1530 | */ |
1549 | int | 1531 | int |
@@ -1623,7 +1605,7 @@ cadet_recv_join_decision (void *cls, | |||
1623 | GNUNET_break_op (0); | 1605 | GNUNET_break_op (0); |
1624 | return GNUNET_SYSERR; | 1606 | return GNUNET_SYSERR; |
1625 | } | 1607 | } |
1626 | if (NULL == chn->grp || GNUNET_NO != chn->grp->is_origin) | 1608 | if (NULL == chn->group || GNUNET_NO != chn->group->is_origin) |
1627 | { | 1609 | { |
1628 | GNUNET_break_op (0); | 1610 | GNUNET_break_op (0); |
1629 | return GNUNET_SYSERR; | 1611 | return GNUNET_SYSERR; |
@@ -1646,7 +1628,7 @@ cadet_recv_join_decision (void *cls, | |||
1646 | hdcsn->peer = chn->peer; | 1628 | hdcsn->peer = chn->peer; |
1647 | GNUNET_memcpy (&hdcsn[1], dcsn, sizeof (*hdcsn) + size); | 1629 | GNUNET_memcpy (&hdcsn[1], dcsn, sizeof (*hdcsn) + size); |
1648 | 1630 | ||
1649 | struct Member *mem = (struct Member *) chn->grp; | 1631 | struct Member *mem = (struct Member *) chn->group; |
1650 | client_send_join_decision (mem, hdcsn); | 1632 | client_send_join_decision (mem, hdcsn); |
1651 | GNUNET_free (hdcsn); | 1633 | GNUNET_free (hdcsn); |
1652 | if (GNUNET_YES == ntohs (dcsn->is_admitted)) | 1634 | if (GNUNET_YES == ntohs (dcsn->is_admitted)) |
@@ -1774,12 +1756,12 @@ cadet_recv_replay_request (void *cls, | |||
1774 | 1756 | ||
1775 | struct GNUNET_CONTAINER_MultiHashMap * | 1757 | struct GNUNET_CONTAINER_MultiHashMap * |
1776 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, | 1758 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, |
1777 | &chn->grp->pub_key_hash); | 1759 | &chn->group->pub_key_hash); |
1778 | if (NULL == grp_replay_req) | 1760 | if (NULL == grp_replay_req) |
1779 | { | 1761 | { |
1780 | grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 1762 | grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
1781 | GNUNET_CONTAINER_multihashmap_put (replay_req_cadet, | 1763 | GNUNET_CONTAINER_multihashmap_put (replay_req_cadet, |
1782 | &chn->grp->pub_key_hash, grp_replay_req, | 1764 | &chn->group->pub_key_hash, grp_replay_req, |
1783 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 1765 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
1784 | } | 1766 | } |
1785 | struct GNUNET_HashCode key_hash; | 1767 | struct GNUNET_HashCode key_hash; |
@@ -1811,6 +1793,88 @@ cadet_recv_replay_response (void *cls, | |||
1811 | 1793 | ||
1812 | 1794 | ||
1813 | /** | 1795 | /** |
1796 | * A new client connected. | ||
1797 | * | ||
1798 | * @param cls NULL | ||
1799 | * @param client client to add | ||
1800 | * @param mq message queue for @a client | ||
1801 | * @return @a client | ||
1802 | */ | ||
1803 | static void * | ||
1804 | client_notify_connect (void *cls, | ||
1805 | struct GNUNET_SERVICE_Client *client, | ||
1806 | struct GNUNET_MQ_Handle *mq) | ||
1807 | { | ||
1808 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client); | ||
1809 | /* FIXME: send connect ACK */ | ||
1810 | |||
1811 | struct Client *c = GNUNET_new (struct Client); | ||
1812 | c->client = client; | ||
1813 | |||
1814 | return c; | ||
1815 | } | ||
1816 | |||
1817 | |||
1818 | /** | ||
1819 | * Called whenever a client is disconnected. | ||
1820 | * Frees our resources associated with that client. | ||
1821 | * | ||
1822 | * @param cls closure | ||
1823 | * @param client identification of the client | ||
1824 | * @param app_ctx must match @a client | ||
1825 | */ | ||
1826 | static void | ||
1827 | client_notify_disconnect (void *cls, | ||
1828 | struct GNUNET_SERVICE_Client *client, | ||
1829 | void *app_ctx) | ||
1830 | { | ||
1831 | struct Client *c = app_ctx; | ||
1832 | struct Group *grp = c->group; | ||
1833 | |||
1834 | if (NULL == grp) | ||
1835 | { | ||
1836 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1837 | "%p User context is NULL in client_disconnect()\n", grp); | ||
1838 | GNUNET_break (0); | ||
1839 | return; | ||
1840 | } | ||
1841 | |||
1842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1843 | "%p Client (%s) disconnected from group %s\n", | ||
1844 | grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member", | ||
1845 | GNUNET_h2s (&grp->pub_key_hash)); | ||
1846 | |||
1847 | struct ClientList *cl = grp->clients_head; | ||
1848 | while (NULL != cl) | ||
1849 | { | ||
1850 | if (cl->client == client) | ||
1851 | { | ||
1852 | GNUNET_CONTAINER_DLL_remove (grp->clients_head, grp->clients_tail, cl); | ||
1853 | GNUNET_free (cl); | ||
1854 | break; | ||
1855 | } | ||
1856 | cl = cl->next; | ||
1857 | } | ||
1858 | |||
1859 | while (GNUNET_YES == replay_req_remove_client (grp, client)); | ||
1860 | |||
1861 | if (NULL == grp->clients_head) | ||
1862 | { /* Last client disconnected. */ | ||
1863 | #if FIXME | ||
1864 | if (NULL != grp->tmit_head) | ||
1865 | { /* Send pending messages via CADET before cleanup. */ | ||
1866 | transmit_message (grp); | ||
1867 | } | ||
1868 | else | ||
1869 | #endif | ||
1870 | { | ||
1871 | cleanup_group (grp); | ||
1872 | } | ||
1873 | } | ||
1874 | } | ||
1875 | |||
1876 | |||
1877 | /** | ||
1814 | * Message handlers for CADET. | 1878 | * Message handlers for CADET. |
1815 | */ | 1879 | */ |
1816 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | 1880 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { |
@@ -1842,12 +1906,11 @@ static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | |||
1842 | */ | 1906 | */ |
1843 | static void | 1907 | static void |
1844 | run (void *cls, | 1908 | run (void *cls, |
1845 | struct GNUNET_SERVER_Handle *srv, | 1909 | const struct GNUNET_CONFIGURATION_Handle *c, |
1846 | const struct GNUNET_CONFIGURATION_Handle *c) | 1910 | struct GNUNET_SERVICE_Handle *svc) |
1847 | { | 1911 | { |
1848 | cfg = c; | 1912 | cfg = c; |
1849 | server = srv; | 1913 | service = svc; |
1850 | GNUNET_SERVER_connect_notify (server, &client_notify_connect, NULL); | ||
1851 | GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer); | 1914 | GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer); |
1852 | 1915 | ||
1853 | stats = GNUNET_STATISTICS_create ("multicast", cfg); | 1916 | stats = GNUNET_STATISTICS_create ("multicast", cfg); |
@@ -1860,32 +1923,56 @@ run (void *cls, | |||
1860 | replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 1923 | replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
1861 | 1924 | ||
1862 | cadet = GNUNET_CADET_connect (cfg, NULL, | 1925 | cadet = GNUNET_CADET_connect (cfg, NULL, |
1863 | &cadet_notify_channel_end, | 1926 | cadet_notify_channel_end, |
1864 | cadet_handlers); | 1927 | cadet_handlers); |
1865 | GNUNET_assert (NULL != cadet); | 1928 | GNUNET_assert (NULL != cadet); |
1866 | 1929 | ||
1867 | nc = GNUNET_SERVER_notification_context_create (server, 1); | ||
1868 | GNUNET_SERVER_add_handlers (server, server_handlers); | ||
1869 | GNUNET_SERVER_disconnect_notify (server, | ||
1870 | &client_notify_disconnect, NULL); | ||
1871 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 1930 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
1872 | NULL); | 1931 | NULL); |
1873 | } | 1932 | } |
1874 | 1933 | ||
1875 | 1934 | ||
1876 | /** | 1935 | /** |
1877 | * The main function for the multicast service. | 1936 | * Define "main" method using service macro. |
1878 | * | 1937 | */ |
1879 | * @param argc number of arguments from the command line | 1938 | GNUNET_SERVICE_MAIN |
1880 | * @param argv command line arguments | 1939 | ("multicast", |
1881 | * @return 0 ok, 1 on error | 1940 | GNUNET_SERVICE_OPTION_NONE, |
1882 | */ | 1941 | run, |
1883 | int | 1942 | client_notify_connect, |
1884 | main (int argc, char *const *argv) | 1943 | client_notify_disconnect, |
1885 | { | 1944 | NULL, |
1886 | return (GNUNET_OK == | 1945 | GNUNET_MQ_hd_fixed_size (client_origin_start, |
1887 | GNUNET_SERVICE_run (argc, argv, "multicast", | 1946 | GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, |
1888 | GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; | 1947 | struct MulticastOriginStartMessage, |
1889 | } | 1948 | NULL), |
1949 | GNUNET_MQ_hd_var_size (client_member_join, | ||
1950 | GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, | ||
1951 | struct MulticastMemberJoinMessage, | ||
1952 | NULL), | ||
1953 | GNUNET_MQ_hd_var_size (client_join_decision, | ||
1954 | GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, | ||
1955 | struct MulticastJoinDecisionMessageHeader, | ||
1956 | NULL), | ||
1957 | GNUNET_MQ_hd_var_size (client_multicast_message, | ||
1958 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, | ||
1959 | struct GNUNET_MULTICAST_MessageHeader, | ||
1960 | NULL), | ||
1961 | GNUNET_MQ_hd_var_size (client_multicast_request, | ||
1962 | GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, | ||
1963 | struct GNUNET_MULTICAST_RequestHeader, | ||
1964 | NULL), | ||
1965 | GNUNET_MQ_hd_fixed_size (client_replay_request, | ||
1966 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, | ||
1967 | struct MulticastReplayRequestMessage, | ||
1968 | NULL), | ||
1969 | GNUNET_MQ_hd_var_size (client_replay_response, | ||
1970 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, | ||
1971 | struct MulticastReplayResponseMessage, | ||
1972 | NULL), | ||
1973 | GNUNET_MQ_hd_var_size (client_replay_response_end, | ||
1974 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END, | ||
1975 | struct MulticastReplayResponseMessage, | ||
1976 | NULL)); | ||
1890 | 1977 | ||
1891 | /* end of gnunet-service-multicast.c */ | 1978 | /* end of gnunet-service-multicast.c */ |