aboutsummaryrefslogtreecommitdiff
path: root/src/multicast
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2016-09-23 21:17:15 +0000
committerGabor X Toth <*@tg-x.net>2016-09-23 21:17:15 +0000
commitc57d130527529e03bfba65f4f61a4a8baabb0e6e (patch)
treeea82ec01238ed4430754398dd0c41505937a135e /src/multicast
parentf5e65b30356f20c7fd6f80fc1a9cb6de8e035505 (diff)
downloadgnunet-c57d130527529e03bfba65f4f61a4a8baabb0e6e.tar.gz
gnunet-c57d130527529e03bfba65f4f61a4a8baabb0e6e.zip
multicast: switch to SERVICE API
Diffstat (limited to 'src/multicast')
-rw-r--r--src/multicast/gnunet-service-multicast.c601
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 @@
38static const struct GNUNET_CONFIGURATION_Handle *cfg; 38static const struct GNUNET_CONFIGURATION_Handle *cfg;
39 39
40/** 40/**
41 * Server handle. 41 * Service handle.
42 */ 42 */
43static struct GNUNET_SERVER_Handle *server; 43static 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;
58static struct GNUNET_STATISTICS_Handle *stats; 58static struct GNUNET_STATISTICS_Handle *stats;
59 59
60/** 60/**
61 * Notification context, simplifies client broadcasts.
62 */
63static 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 */
107static struct GNUNET_CONTAINER_MultiHashMap *replay_req_client; 102static 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 */
202struct Group 198struct 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 */
237struct Origin 238struct 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 */
261struct Member 262struct 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 */
324struct Client {
325 struct GNUNET_SERVICE_Client *client;
326 struct Group *group;
327};
328
329
320struct ReplayRequestKey 330struct ReplayRequestKey
321{ 331{
322 uint64_t fragment_id; 332 uint64_t fragment_id;
@@ -354,7 +364,7 @@ shutdown_task (void *cls)
354static void 364static void
355cleanup_origin (struct Origin *orig) 365cleanup_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)
371static void 381static void
372cleanup_member (struct Member *mem) 382cleanup_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
401cleanup_group (struct Group *grp) 411cleanup_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 */
471static int 481static int
472replay_req_remove_client (struct Group *grp, struct GNUNET_SERVER_Client *client) 482replay_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 */
508static void
509client_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 */
563static void 513static void
564client_send (struct GNUNET_SERVER_Client *client, 514client_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 *
785cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer) 741cadet_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)
806static void 762static void
807cadet_send_join_request (struct Member *mem) 763cadet_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 */
959static void 915static void
960client_recv_origin_start (void *cls, struct GNUNET_SERVER_Client *client, 916handle_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); 967static int
1007 GNUNET_SERVER_receive_done (client, GNUNET_OK); 968check_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 */
1014static void 994static void
1015client_recv_member_join (void *cls, struct GNUNET_SERVER_Client *client, 995handle_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
1150client_send_join_decision (struct Member *mem, 1124client_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
1143static int
1144check_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 */
1172static void 1154static void
1173client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client, 1155handle_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
1198static int
1199check_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 */
1220static void 1209static void
1221client_recv_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, 1210handle_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
1253static int
1254check_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 */
1267static void 1264static void
1268client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, 1265handle_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 */
1327static void 1326static void
1328client_recv_replay_request (void *cls, struct GNUNET_SERVER_Client *client, 1327handle_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
1403static int
1404check_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 */
1406static void 1414static void
1407client_recv_replay_response_end (void *cls, struct GNUNET_SERVER_Client *client, 1415handle_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
1451static int
1452check_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 */
1448static void 1473static void
1449client_recv_replay_response (void *cls, struct GNUNET_SERVER_Client *client, 1474handle_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 */
1506static void
1507client_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 */
1517static 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 */
1549int 1531int
@@ -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 */
1803static void *
1804client_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 */
1826static void
1827client_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 */
1816static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { 1880static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
@@ -1842,12 +1906,11 @@ static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
1842 */ 1906 */
1843static void 1907static void
1844run (void *cls, 1908run (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 1938GNUNET_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,
1883int 1942 client_notify_connect,
1884main (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 */