aboutsummaryrefslogtreecommitdiff
path: root/src/multicast/gnunet-service-multicast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/multicast/gnunet-service-multicast.c')
-rw-r--r--src/multicast/gnunet-service-multicast.c248
1 files changed, 158 insertions, 90 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index 2f4dc8a14..ba1086cc5 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -137,6 +137,7 @@ struct Channel
137 */ 137 */
138 struct GNUNET_CADET_Channel *channel; 138 struct GNUNET_CADET_Channel *channel;
139 139
140 // FIXME: not used
140 /** 141 /**
141 * CADET transmission handle. 142 * CADET transmission handle.
142 */ 143 */
@@ -228,7 +229,7 @@ struct Group
228 /** 229 /**
229 * Is the client disconnected? #GNUNET_YES or #GNUNET_NO 230 * Is the client disconnected? #GNUNET_YES or #GNUNET_NO
230 */ 231 */
231 uint8_t disconnected; 232 uint8_t is_disconnected;
232 233
233 /** 234 /**
234 * Is this an origin (#GNUNET_YES), or member (#GNUNET_NO)? 235 * Is this an origin (#GNUNET_YES), or member (#GNUNET_NO)?
@@ -365,6 +366,8 @@ client_send_join_decision (struct Member *mem,
365static void 366static void
366shutdown_task (void *cls) 367shutdown_task (void *cls)
367{ 368{
369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
370 "shutting down\n");
368 if (NULL != cadet) 371 if (NULL != cadet)
369 { 372 {
370 GNUNET_CADET_disconnect (cadet); 373 GNUNET_CADET_disconnect (cadet);
@@ -420,6 +423,11 @@ cleanup_member (struct Member *mem)
420 GNUNET_free (mem->join_dcsn); 423 GNUNET_free (mem->join_dcsn);
421 mem->join_dcsn = NULL; 424 mem->join_dcsn = NULL;
422 } 425 }
426 if (NULL != mem->origin_channel)
427 {
428 GNUNET_CADET_channel_destroy (mem->origin_channel->channel);
429 mem->origin_channel = NULL;
430 }
423 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem); 431 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem);
424 GNUNET_free (mem); 432 GNUNET_free (mem);
425} 433}
@@ -553,36 +561,47 @@ client_send (struct GNUNET_SERVICE_Client *client,
553 * Send message to all clients connected to the group. 561 * Send message to all clients connected to the group.
554 */ 562 */
555static void 563static void
556client_send_group (const struct Group *grp, 564client_send_group_keep_envelope (const struct Group *grp,
557 const struct GNUNET_MessageHeader *msg) 565 struct GNUNET_MQ_Envelope *env)
558{ 566{
559 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 567 struct ClientList *cli = grp->clients_head;
560 "%p Sending message to all clients of the group.\n", grp);
561 568
562 struct ClientList *cl = grp->clients_head; 569 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
563 while (NULL != cl) 570 "%p Sending message to all clients of the group.\n",
571 grp);
572 while (NULL != cli)
564 { 573 {
565 struct GNUNET_MQ_Envelope * 574 GNUNET_MQ_send_copy (GNUNET_SERVICE_client_get_mq (cli->client),
566 env = GNUNET_MQ_msg_copy (msg); 575 env);
567 576 cli = cli->next;
568 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cl->client),
569 env);
570 cl = cl->next;
571 } 577 }
572} 578}
573 579
574 580
575/** 581/**
582 * Send message to all clients connected to the group and
583 * takes care of freeing @env.
584 */
585static void
586client_send_group (const struct Group *grp,
587 struct GNUNET_MQ_Envelope *env)
588{
589 client_send_group_keep_envelope (grp, env);
590 GNUNET_MQ_discard (env);
591}
592
593
594/**
576 * Iterator callback for sending a message to origin clients. 595 * Iterator callback for sending a message to origin clients.
577 */ 596 */
578static int 597static int
579client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 598client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
580 void *origin) 599 void *origin)
581{ 600{
582 const struct GNUNET_MessageHeader *msg = cls; 601 struct GNUNET_MQ_Envelope *env = cls;
583 struct Member *orig = origin; 602 struct Member *orig = origin;
584 603
585 client_send_group (&orig->group, msg); 604 client_send_group_keep_envelope (&orig->group, env);
586 return GNUNET_YES; 605 return GNUNET_YES;
587} 606}
588 607
@@ -594,12 +613,12 @@ static int
594client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 613client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
595 void *member) 614 void *member)
596{ 615{
597 const struct GNUNET_MessageHeader *msg = cls; 616 struct GNUNET_MQ_Envelope *env = cls;
598 struct Member *mem = member; 617 struct Member *mem = member;
599 618
600 if (NULL != mem->join_dcsn) 619 if (NULL != mem->join_dcsn)
601 { /* Only send message to admitted members */ 620 { /* Only send message to admitted members */
602 client_send_group (&mem->group, msg); 621 client_send_group_keep_envelope (&mem->group, env);
603 } 622 }
604 return GNUNET_YES; 623 return GNUNET_YES;
605} 624}
@@ -615,15 +634,16 @@ client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
615 */ 634 */
616static int 635static int
617client_send_all (struct GNUNET_HashCode *pub_key_hash, 636client_send_all (struct GNUNET_HashCode *pub_key_hash,
618 const struct GNUNET_MessageHeader *msg) 637 struct GNUNET_MQ_Envelope *env)
619{ 638{
620 int n = 0; 639 int n = 0;
621 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash, 640 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
622 client_send_origin_cb, 641 client_send_origin_cb,
623 (void *) msg); 642 (void *) env);
624 n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash, 643 n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash,
625 client_send_member_cb, 644 client_send_member_cb,
626 (void *) msg); 645 (void *) env);
646 GNUNET_MQ_discard (env);
627 return n; 647 return n;
628} 648}
629 649
@@ -636,14 +656,14 @@ client_send_all (struct GNUNET_HashCode *pub_key_hash,
636 */ 656 */
637static int 657static int
638client_send_random (struct GNUNET_HashCode *pub_key_hash, 658client_send_random (struct GNUNET_HashCode *pub_key_hash,
639 const struct GNUNET_MessageHeader *msg) 659 struct GNUNET_MQ_Envelope *env)
640{ 660{
641 int n = 0; 661 int n = 0;
642 n = GNUNET_CONTAINER_multihashmap_get_random (origins, client_send_origin_cb, 662 n = GNUNET_CONTAINER_multihashmap_get_random (origins, client_send_origin_cb,
643 (void *) msg); 663 (void *) env);
644 if (n <= 0) 664 if (n <= 0)
645 n = GNUNET_CONTAINER_multihashmap_get_random (members, client_send_member_cb, 665 n = GNUNET_CONTAINER_multihashmap_get_random (members, client_send_member_cb,
646 (void *) msg); 666 (void *) env);
647 return n; 667 return n;
648} 668}
649 669
@@ -658,12 +678,12 @@ client_send_random (struct GNUNET_HashCode *pub_key_hash,
658 */ 678 */
659static int 679static int
660client_send_origin (struct GNUNET_HashCode *pub_key_hash, 680client_send_origin (struct GNUNET_HashCode *pub_key_hash,
661 const struct GNUNET_MessageHeader *msg) 681 struct GNUNET_MQ_Envelope *env)
662{ 682{
663 int n = 0; 683 int n = 0;
664 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash, 684 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
665 client_send_origin_cb, 685 client_send_origin_cb,
666 (void *) msg); 686 (void *) env);
667 return n; 687 return n;
668} 688}
669 689
@@ -677,17 +697,12 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash,
677static void 697static void
678client_send_ack (struct GNUNET_HashCode *pub_key_hash) 698client_send_ack (struct GNUNET_HashCode *pub_key_hash)
679{ 699{
700 struct GNUNET_MQ_Envelope *env;
701
680 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 702 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
681 "Sending message ACK to client.\n"); 703 "Sending message ACK to client.\n");
682 704 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_FRAGMENT_ACK);
683 static struct GNUNET_MessageHeader *msg = NULL; 705 client_send_all (pub_key_hash, env);
684 if (NULL == msg)
685 {
686 msg = GNUNET_malloc (sizeof (*msg));
687 msg->type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_FRAGMENT_ACK);
688 msg->size = htons (sizeof (*msg));
689 }
690 client_send_all (pub_key_hash, msg);
691} 706}
692 707
693 708
@@ -983,7 +998,8 @@ handle_cadet_join_request (void *cls,
983 chn->peer = req->peer; 998 chn->peer = req->peer;
984 chn->join_status = JOIN_WAITING; 999 chn->join_status = JOIN_WAITING;
985 1000
986 client_send_all (&group_pub_hash, &req->header); 1001 client_send_all (&group_pub_hash,
1002 GNUNET_MQ_msg_copy (&req->header));
987} 1003}
988 1004
989 1005
@@ -1102,7 +1118,8 @@ handle_cadet_message (void *cls,
1102{ 1118{
1103 struct Channel *chn = cls; 1119 struct Channel *chn = cls;
1104 GNUNET_CADET_receive_done (chn->channel); 1120 GNUNET_CADET_receive_done (chn->channel);
1105 client_send_all (&chn->group_pub_hash, &msg->header); 1121 client_send_all (&chn->group_pub_hash,
1122 GNUNET_MQ_msg_copy (&msg->header));
1106} 1123}
1107 1124
1108 1125
@@ -1153,30 +1170,32 @@ handle_cadet_request (void *cls,
1153{ 1170{
1154 struct Channel *chn = cls; 1171 struct Channel *chn = cls;
1155 GNUNET_CADET_receive_done (chn->channel); 1172 GNUNET_CADET_receive_done (chn->channel);
1156 client_send_origin (&chn->group_pub_hash, &req->header); 1173 client_send_origin (&chn->group_pub_hash,
1174 GNUNET_MQ_msg_copy (&req->header));
1157} 1175}
1158 1176
1159 1177
1160static int 1178// FIXME: do checks in handle_cadet_replay_request
1161check_cadet_replay_request (void *cls, 1179//static int
1162 const struct MulticastReplayRequestMessage *req) 1180//check_cadet_replay_request (void *cls,
1163{ 1181// const struct MulticastReplayRequestMessage *req)
1164 uint16_t size = ntohs (req->header.size); 1182//{
1165 if (size < sizeof (*req)) 1183// uint16_t size = ntohs (req->header.size);
1166 { 1184// if (size < sizeof (*req))
1167 GNUNET_break_op (0); 1185// {
1168 return GNUNET_SYSERR; 1186// GNUNET_break_op (0);
1169 } 1187// return GNUNET_SYSERR;
1170 1188// }
1171 struct Channel *chn = cls; 1189//
1172 if (NULL == chn) 1190// struct Channel *chn = cls;
1173 { 1191// if (NULL == chn)
1174 GNUNET_break_op (0); 1192// {
1175 return GNUNET_SYSERR; 1193// GNUNET_break_op (0);
1176 } 1194// return GNUNET_SYSERR;
1177 1195// }
1178 return GNUNET_OK; 1196//
1179} 1197// return GNUNET_OK;
1198//}
1180 1199
1181 1200
1182/** 1201/**
@@ -1187,6 +1206,7 @@ handle_cadet_replay_request (void *cls,
1187 const struct MulticastReplayRequestMessage *req) 1206 const struct MulticastReplayRequestMessage *req)
1188{ 1207{
1189 struct Channel *chn = cls; 1208 struct Channel *chn = cls;
1209
1190 GNUNET_CADET_receive_done (chn->channel); 1210 GNUNET_CADET_receive_done (chn->channel);
1191 1211
1192 struct MulticastReplayRequestMessage rep = *req; 1212 struct MulticastReplayRequestMessage rep = *req;
@@ -1203,12 +1223,16 @@ handle_cadet_replay_request (void *cls,
1203 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1223 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1204 } 1224 }
1205 struct GNUNET_HashCode key_hash; 1225 struct GNUNET_HashCode key_hash;
1206 replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset, 1226 replay_key_hash (rep.fragment_id,
1207 rep.flags, &key_hash); 1227 rep.message_id,
1228 rep.fragment_offset,
1229 rep.flags,
1230 &key_hash);
1208 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn, 1231 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
1209 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1232 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1210 1233
1211 client_send_random (&chn->group_pub_hash, &rep.header); 1234 client_send_random (&chn->group_pub_hash,
1235 GNUNET_MQ_msg_copy (&rep.header));
1212} 1236}
1213 1237
1214 1238
@@ -1290,10 +1314,10 @@ cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer)
1290 struct MulticastJoinDecisionMessageHeader, 1314 struct MulticastJoinDecisionMessageHeader,
1291 chn), 1315 chn),
1292 1316
1293 GNUNET_MQ_hd_var_size (cadet_replay_request, 1317 GNUNET_MQ_hd_fixed_size (cadet_replay_request,
1294 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 1318 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1295 struct MulticastReplayRequestMessage, 1319 struct MulticastReplayRequestMessage,
1296 chn), 1320 chn),
1297 1321
1298 GNUNET_MQ_hd_var_size (cadet_replay_response, 1322 GNUNET_MQ_hd_var_size (cadet_replay_response,
1299 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 1323 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
@@ -1357,6 +1381,7 @@ handle_client_origin_start (void *cls,
1357 grp->is_origin = GNUNET_YES; 1381 grp->is_origin = GNUNET_YES;
1358 grp->pub_key = pub_key; 1382 grp->pub_key = pub_key;
1359 grp->pub_key_hash = pub_key_hash; 1383 grp->pub_key_hash = pub_key_hash;
1384 grp->is_disconnected = GNUNET_NO;
1360 1385
1361 GNUNET_CONTAINER_multihashmap_put (origins, &grp->pub_key_hash, orig, 1386 GNUNET_CONTAINER_multihashmap_put (origins, &grp->pub_key_hash, orig,
1362 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1387 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
@@ -1379,10 +1404,10 @@ handle_client_origin_start (void *cls,
1379 struct MulticastJoinRequestMessage, 1404 struct MulticastJoinRequestMessage,
1380 grp), 1405 grp),
1381 1406
1382 GNUNET_MQ_hd_var_size (cadet_replay_request, 1407 GNUNET_MQ_hd_fixed_size (cadet_replay_request,
1383 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 1408 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1384 struct MulticastReplayRequestMessage, 1409 struct MulticastReplayRequestMessage,
1385 grp), 1410 grp),
1386 1411
1387 GNUNET_MQ_hd_var_size (cadet_replay_response, 1412 GNUNET_MQ_hd_var_size (cadet_replay_response,
1388 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 1413 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
@@ -1484,6 +1509,7 @@ handle_client_member_join (void *cls,
1484 grp->is_origin = GNUNET_NO; 1509 grp->is_origin = GNUNET_NO;
1485 grp->pub_key = msg->group_pub_key; 1510 grp->pub_key = msg->group_pub_key;
1486 grp->pub_key_hash = pub_key_hash; 1511 grp->pub_key_hash = pub_key_hash;
1512 grp->is_disconnected = GNUNET_NO;
1487 group_set_cadet_port_hash (grp); 1513 group_set_cadet_port_hash (grp);
1488 1514
1489 if (NULL == grp_mem) 1515 if (NULL == grp_mem)
@@ -1494,7 +1520,8 @@ handle_client_member_join (void *cls,
1494 } 1520 }
1495 GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem->pub_key_hash, mem, 1521 GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem->pub_key_hash, mem,
1496 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1522 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1497 1523
1524 // FIXME: should the members hash map have option UNIQUE_FAST?
1498 GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem, 1525 GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem,
1499 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1526 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1500 } 1527 }
@@ -1509,10 +1536,11 @@ handle_client_member_join (void *cls,
1509 1536
1510 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&mem->pub_key); 1537 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&mem->pub_key);
1511 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1512 "Client connected to group %s as member %s (%s).\n", 1539 "Client connected to group %s as member %s (%s). size = %d\n",
1513 GNUNET_h2s (&grp->pub_key_hash), 1540 GNUNET_h2s (&grp->pub_key_hash),
1514 GNUNET_h2s2 (&mem->pub_key_hash), 1541 GNUNET_h2s2 (&mem->pub_key_hash),
1515 str); 1542 str,
1543 GNUNET_CONTAINER_multihashmap_size (members));
1516 GNUNET_free (str); 1544 GNUNET_free (str);
1517 1545
1518 if (NULL != mem->join_dcsn) 1546 if (NULL != mem->join_dcsn)
@@ -1567,7 +1595,9 @@ handle_client_member_join (void *cls,
1567 GNUNET_free (mem->join_req); 1595 GNUNET_free (mem->join_req);
1568 mem->join_req = req; 1596 mem->join_req = req;
1569 1597
1570 if (0 == client_send_origin (&grp->pub_key_hash, &mem->join_req->header)) 1598 if (0 ==
1599 client_send_origin (&grp->pub_key_hash,
1600 GNUNET_MQ_msg_copy (&mem->join_req->header)))
1571 { /* No local origins, send to remote origin */ 1601 { /* No local origins, send to remote origin */
1572 cadet_send_join_request (mem); 1602 cadet_send_join_request (mem);
1573 } 1603 }
@@ -1580,7 +1610,7 @@ static void
1580client_send_join_decision (struct Member *mem, 1610client_send_join_decision (struct Member *mem,
1581 const struct MulticastJoinDecisionMessageHeader *hdcsn) 1611 const struct MulticastJoinDecisionMessageHeader *hdcsn)
1582{ 1612{
1583 client_send_group (&mem->group, &hdcsn->header); 1613 client_send_group (&mem->group, GNUNET_MQ_msg_copy (&hdcsn->header));
1584 1614
1585 const struct MulticastJoinDecisionMessage * 1615 const struct MulticastJoinDecisionMessage *
1586 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; 1616 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
@@ -1621,8 +1651,9 @@ handle_client_join_decision (void *cls,
1621 GNUNET_SERVICE_client_drop (client); 1651 GNUNET_SERVICE_client_drop (client);
1622 return; 1652 return;
1623 } 1653 }
1654 GNUNET_assert (GNUNET_NO == grp->is_disconnected);
1624 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1655 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1625 "%p Got join decision from client for group %s..\n", 1656 "%p got join decision from client for group %s..\n",
1626 grp, GNUNET_h2s (&grp->pub_key_hash)); 1657 grp, GNUNET_h2s (&grp->pub_key_hash));
1627 1658
1628 struct GNUNET_CONTAINER_MultiHashMap * 1659 struct GNUNET_CONTAINER_MultiHashMap *
@@ -1652,6 +1683,32 @@ handle_client_join_decision (void *cls,
1652} 1683}
1653 1684
1654 1685
1686static void
1687handle_client_part_request (void *cls,
1688 const struct GNUNET_MessageHeader *msg)
1689{
1690 struct Client *c = cls;
1691 struct GNUNET_SERVICE_Client *client = c->client;
1692 struct Group *grp = c->group;
1693 struct GNUNET_MQ_Envelope *env;
1694
1695 if (NULL == grp)
1696 {
1697 GNUNET_break (0);
1698 GNUNET_SERVICE_client_drop (client);
1699 return;
1700 }
1701 GNUNET_assert (GNUNET_NO == grp->is_disconnected);
1702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1703 "%p got part request from client for group %s.\n",
1704 grp, GNUNET_h2s (&grp->pub_key_hash));
1705 grp->is_disconnected = GNUNET_YES;
1706 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK);
1707 client_send_group (grp, env);
1708 GNUNET_SERVICE_client_continue (client);
1709}
1710
1711
1655static int 1712static int
1656check_client_multicast_message (void *cls, 1713check_client_multicast_message (void *cls,
1657 const struct GNUNET_MULTICAST_MessageHeader *msg) 1714 const struct GNUNET_MULTICAST_MessageHeader *msg)
@@ -1667,6 +1724,7 @@ static void
1667handle_client_multicast_message (void *cls, 1724handle_client_multicast_message (void *cls,
1668 const struct GNUNET_MULTICAST_MessageHeader *msg) 1725 const struct GNUNET_MULTICAST_MessageHeader *msg)
1669{ 1726{
1727 // FIXME: what if GNUNET_YES == grp->is_disconnected? Do we allow sending messages?
1670 struct Client *c = cls; 1728 struct Client *c = cls;
1671 struct GNUNET_SERVICE_Client *client = c->client; 1729 struct GNUNET_SERVICE_Client *client = c->client;
1672 struct Group *grp = c->group; 1730 struct Group *grp = c->group;
@@ -1680,6 +1738,7 @@ handle_client_multicast_message (void *cls,
1680 GNUNET_assert (GNUNET_YES == grp->is_origin); 1738 GNUNET_assert (GNUNET_YES == grp->is_origin);
1681 struct Origin *orig = grp->origin; 1739 struct Origin *orig = grp->origin;
1682 1740
1741 // FIXME: use GNUNET_MQ_msg_copy
1683 /* FIXME: yucky, should use separate message structs for P2P and CS! */ 1742 /* FIXME: yucky, should use separate message structs for P2P and CS! */
1684 struct GNUNET_MULTICAST_MessageHeader * 1743 struct GNUNET_MULTICAST_MessageHeader *
1685 out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (&msg->header); 1744 out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (&msg->header);
@@ -1696,7 +1755,7 @@ handle_client_multicast_message (void *cls,
1696 GNUNET_assert (0); 1755 GNUNET_assert (0);
1697 } 1756 }
1698 1757
1699 client_send_all (&grp->pub_key_hash, &out->header); 1758 client_send_all (&grp->pub_key_hash, GNUNET_MQ_msg_copy (&out->header));
1700 cadet_send_children (&grp->pub_key_hash, &out->header); 1759 cadet_send_children (&grp->pub_key_hash, &out->header);
1701 client_send_ack (&grp->pub_key_hash); 1760 client_send_ack (&grp->pub_key_hash);
1702 GNUNET_free (out); 1761 GNUNET_free (out);
@@ -1730,6 +1789,7 @@ handle_client_multicast_request (void *cls,
1730 GNUNET_SERVICE_client_drop (client); 1789 GNUNET_SERVICE_client_drop (client);
1731 return; 1790 return;
1732 } 1791 }
1792 GNUNET_assert (GNUNET_NO == grp->is_disconnected);
1733 GNUNET_assert (GNUNET_NO == grp->is_origin); 1793 GNUNET_assert (GNUNET_NO == grp->is_origin);
1734 struct Member *mem = grp->member; 1794 struct Member *mem = grp->member;
1735 1795
@@ -1751,7 +1811,9 @@ handle_client_multicast_request (void *cls,
1751 } 1811 }
1752 1812
1753 uint8_t send_ack = GNUNET_YES; 1813 uint8_t send_ack = GNUNET_YES;
1754 if (0 == client_send_origin (&grp->pub_key_hash, &out->header)) 1814 if (0 ==
1815 client_send_origin (&grp->pub_key_hash,
1816 GNUNET_MQ_msg_copy (&out->header)))
1755 { /* No local origins, send to remote origin */ 1817 { /* No local origins, send to remote origin */
1756 if (NULL != mem->origin_channel) 1818 if (NULL != mem->origin_channel)
1757 { 1819 {
@@ -1792,6 +1854,7 @@ handle_client_replay_request (void *cls,
1792 GNUNET_SERVICE_client_drop (client); 1854 GNUNET_SERVICE_client_drop (client);
1793 return; 1855 return;
1794 } 1856 }
1857 GNUNET_assert (GNUNET_NO == grp->is_disconnected);
1795 GNUNET_assert (GNUNET_NO == grp->is_origin); 1858 GNUNET_assert (GNUNET_NO == grp->is_origin);
1796 struct Member *mem = grp->member; 1859 struct Member *mem = grp->member;
1797 1860
@@ -1812,7 +1875,9 @@ handle_client_replay_request (void *cls,
1812 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client, 1875 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client,
1813 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1876 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1814 1877
1815 if (0 == client_send_origin (&grp->pub_key_hash, &rep->header)) 1878 if (0 ==
1879 client_send_origin (&grp->pub_key_hash,
1880 GNUNET_MQ_msg_copy (&rep->header)))
1816 { /* No local origin, replay from remote members / origin. */ 1881 { /* No local origin, replay from remote members / origin. */
1817 if (NULL != mem->origin_channel) 1882 if (NULL != mem->origin_channel)
1818 { 1883 {
@@ -1821,6 +1886,7 @@ handle_client_replay_request (void *cls,
1821 else 1886 else
1822 { 1887 {
1823 /* FIXME: not yet connected to origin */ 1888 /* FIXME: not yet connected to origin */
1889 GNUNET_assert (0);
1824 GNUNET_SERVICE_client_drop (client); 1890 GNUNET_SERVICE_client_drop (client);
1825 return; 1891 return;
1826 } 1892 }
@@ -1880,6 +1946,7 @@ handle_client_replay_response_end (void *cls,
1880 GNUNET_SERVICE_client_drop (client); 1946 GNUNET_SERVICE_client_drop (client);
1881 return; 1947 return;
1882 } 1948 }
1949 GNUNET_assert (GNUNET_NO == grp->is_disconnected);
1883 1950
1884 struct GNUNET_HashCode key_hash; 1951 struct GNUNET_HashCode key_hash;
1885 replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset, 1952 replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset,
@@ -1939,6 +2006,7 @@ handle_client_replay_response (void *cls,
1939 GNUNET_SERVICE_client_drop (client); 2006 GNUNET_SERVICE_client_drop (client);
1940 return; 2007 return;
1941 } 2008 }
2009 GNUNET_assert (GNUNET_NO == grp->is_disconnected);
1942 2010
1943 const struct GNUNET_MessageHeader *msg = &res->header; 2011 const struct GNUNET_MessageHeader *msg = &res->header;
1944 if (GNUNET_MULTICAST_REC_OK == res->error_code) 2012 if (GNUNET_MULTICAST_REC_OK == res->error_code)
@@ -2033,9 +2101,14 @@ client_notify_disconnect (void *cls,
2033 grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member", 2101 grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member",
2034 GNUNET_h2s (&grp->pub_key_hash)); 2102 GNUNET_h2s (&grp->pub_key_hash));
2035 2103
2104 // FIXME (due to protocol change): here we must not remove all clients,
2105 // only the one we were notified about!
2036 struct ClientList *cl = grp->clients_head; 2106 struct ClientList *cl = grp->clients_head;
2037 while (NULL != cl) 2107 while (NULL != cl)
2038 { 2108 {
2109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2110 "iterating clients for group %p\n",
2111 grp);
2039 if (cl->client == client) 2112 if (cl->client == client)
2040 { 2113 {
2041 GNUNET_CONTAINER_DLL_remove (grp->clients_head, grp->clients_tail, cl); 2114 GNUNET_CONTAINER_DLL_remove (grp->clients_head, grp->clients_tail, cl);
@@ -2049,16 +2122,7 @@ client_notify_disconnect (void *cls,
2049 2122
2050 if (NULL == grp->clients_head) 2123 if (NULL == grp->clients_head)
2051 { /* Last client disconnected. */ 2124 { /* Last client disconnected. */
2052#if FIXME 2125 cleanup_group (grp);
2053 if (NULL != grp->tmit_head)
2054 { /* Send pending messages via CADET before cleanup. */
2055 transmit_message (grp);
2056 }
2057 else
2058#endif
2059 {
2060 cleanup_group (grp);
2061 }
2062 } 2126 }
2063} 2127}
2064 2128
@@ -2103,9 +2167,9 @@ run (void *cls,
2103GNUNET_SERVICE_MAIN 2167GNUNET_SERVICE_MAIN
2104("multicast", 2168("multicast",
2105 GNUNET_SERVICE_OPTION_NONE, 2169 GNUNET_SERVICE_OPTION_NONE,
2106 run, 2170 &run,
2107 client_notify_connect, 2171 &client_notify_connect,
2108 client_notify_disconnect, 2172 &client_notify_disconnect,
2109 NULL, 2173 NULL,
2110 GNUNET_MQ_hd_fixed_size (client_origin_start, 2174 GNUNET_MQ_hd_fixed_size (client_origin_start,
2111 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 2175 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START,
@@ -2119,6 +2183,10 @@ GNUNET_SERVICE_MAIN
2119 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 2183 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
2120 struct MulticastJoinDecisionMessageHeader, 2184 struct MulticastJoinDecisionMessageHeader,
2121 NULL), 2185 NULL),
2186 GNUNET_MQ_hd_fixed_size (client_part_request,
2187 GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST,
2188 struct GNUNET_MessageHeader,
2189 NULL),
2122 GNUNET_MQ_hd_var_size (client_multicast_message, 2190 GNUNET_MQ_hd_var_size (client_multicast_message,
2123 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 2191 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
2124 struct GNUNET_MULTICAST_MessageHeader, 2192 struct GNUNET_MULTICAST_MessageHeader,