aboutsummaryrefslogtreecommitdiff
path: root/src/multicast
diff options
context:
space:
mode:
authorlurchi <lurchi@strangeplace.net>2017-11-24 21:54:31 +0100
committerlurchi <lurchi@strangeplace.net>2017-11-24 21:54:31 +0100
commit9cf0e753f26488dfde60967ae0184cf986902464 (patch)
tree54b4619f6191f98d99a7bf14fbc82680a225d902 /src/multicast
parentc030c80e458957dd78a5ac37340524f5b606c9b6 (diff)
downloadgnunet-9cf0e753f26488dfde60967ae0184cf986902464.tar.gz
gnunet-9cf0e753f26488dfde60967ae0184cf986902464.zip
introduce part request / part ack messages (for leaving multicast groups) and related fixes
Diffstat (limited to 'src/multicast')
-rw-r--r--src/multicast/gnunet-service-multicast.c208
-rw-r--r--src/multicast/multicast_api.c51
2 files changed, 156 insertions, 103 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index 2f4dc8a14..11f3c08b7 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -553,36 +553,47 @@ client_send (struct GNUNET_SERVICE_Client *client,
553 * Send message to all clients connected to the group. 553 * Send message to all clients connected to the group.
554 */ 554 */
555static void 555static void
556client_send_group (const struct Group *grp, 556client_send_group_keep_envelope (const struct Group *grp,
557 const struct GNUNET_MessageHeader *msg) 557 struct GNUNET_MQ_Envelope *env)
558{ 558{
559 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 559 struct ClientList *cli = grp->clients_head;
560 "%p Sending message to all clients of the group.\n", grp);
561 560
562 struct ClientList *cl = grp->clients_head; 561 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
563 while (NULL != cl) 562 "%p Sending message to all clients of the group.\n",
563 grp);
564 while (NULL != cli)
564 { 565 {
565 struct GNUNET_MQ_Envelope * 566 GNUNET_MQ_send_copy (GNUNET_SERVICE_client_get_mq (cli->client),
566 env = GNUNET_MQ_msg_copy (msg); 567 env);
567 568 cli = cli->next;
568 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cl->client),
569 env);
570 cl = cl->next;
571 } 569 }
572} 570}
573 571
574 572
575/** 573/**
574 * Send message to all clients connected to the group and
575 * takes care of freeing @env.
576 */
577static void
578client_send_group (const struct Group *grp,
579 struct GNUNET_MQ_Envelope *env)
580{
581 client_send_group_keep_envelope (grp, env);
582 GNUNET_MQ_discard (env);
583}
584
585
586/**
576 * Iterator callback for sending a message to origin clients. 587 * Iterator callback for sending a message to origin clients.
577 */ 588 */
578static int 589static int
579client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 590client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
580 void *origin) 591 void *origin)
581{ 592{
582 const struct GNUNET_MessageHeader *msg = cls; 593 struct GNUNET_MQ_Envelope *env = cls;
583 struct Member *orig = origin; 594 struct Member *orig = origin;
584 595
585 client_send_group (&orig->group, msg); 596 client_send_group_keep_envelope (&orig->group, env);
586 return GNUNET_YES; 597 return GNUNET_YES;
587} 598}
588 599
@@ -594,12 +605,12 @@ static int
594client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 605client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
595 void *member) 606 void *member)
596{ 607{
597 const struct GNUNET_MessageHeader *msg = cls; 608 struct GNUNET_MQ_Envelope *env = cls;
598 struct Member *mem = member; 609 struct Member *mem = member;
599 610
600 if (NULL != mem->join_dcsn) 611 if (NULL != mem->join_dcsn)
601 { /* Only send message to admitted members */ 612 { /* Only send message to admitted members */
602 client_send_group (&mem->group, msg); 613 client_send_group_keep_envelope (&mem->group, env);
603 } 614 }
604 return GNUNET_YES; 615 return GNUNET_YES;
605} 616}
@@ -615,15 +626,16 @@ client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
615 */ 626 */
616static int 627static int
617client_send_all (struct GNUNET_HashCode *pub_key_hash, 628client_send_all (struct GNUNET_HashCode *pub_key_hash,
618 const struct GNUNET_MessageHeader *msg) 629 struct GNUNET_MQ_Envelope *env)
619{ 630{
620 int n = 0; 631 int n = 0;
621 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash, 632 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
622 client_send_origin_cb, 633 client_send_origin_cb,
623 (void *) msg); 634 (void *) env);
624 n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash, 635 n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash,
625 client_send_member_cb, 636 client_send_member_cb,
626 (void *) msg); 637 (void *) env);
638 GNUNET_MQ_discard (env);
627 return n; 639 return n;
628} 640}
629 641
@@ -636,14 +648,14 @@ client_send_all (struct GNUNET_HashCode *pub_key_hash,
636 */ 648 */
637static int 649static int
638client_send_random (struct GNUNET_HashCode *pub_key_hash, 650client_send_random (struct GNUNET_HashCode *pub_key_hash,
639 const struct GNUNET_MessageHeader *msg) 651 struct GNUNET_MQ_Envelope *env)
640{ 652{
641 int n = 0; 653 int n = 0;
642 n = GNUNET_CONTAINER_multihashmap_get_random (origins, client_send_origin_cb, 654 n = GNUNET_CONTAINER_multihashmap_get_random (origins, client_send_origin_cb,
643 (void *) msg); 655 (void *) env);
644 if (n <= 0) 656 if (n <= 0)
645 n = GNUNET_CONTAINER_multihashmap_get_random (members, client_send_member_cb, 657 n = GNUNET_CONTAINER_multihashmap_get_random (members, client_send_member_cb,
646 (void *) msg); 658 (void *) env);
647 return n; 659 return n;
648} 660}
649 661
@@ -658,12 +670,12 @@ client_send_random (struct GNUNET_HashCode *pub_key_hash,
658 */ 670 */
659static int 671static int
660client_send_origin (struct GNUNET_HashCode *pub_key_hash, 672client_send_origin (struct GNUNET_HashCode *pub_key_hash,
661 const struct GNUNET_MessageHeader *msg) 673 struct GNUNET_MQ_Envelope *env)
662{ 674{
663 int n = 0; 675 int n = 0;
664 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash, 676 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
665 client_send_origin_cb, 677 client_send_origin_cb,
666 (void *) msg); 678 (void *) env);
667 return n; 679 return n;
668} 680}
669 681
@@ -677,17 +689,12 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash,
677static void 689static void
678client_send_ack (struct GNUNET_HashCode *pub_key_hash) 690client_send_ack (struct GNUNET_HashCode *pub_key_hash)
679{ 691{
692 struct GNUNET_MQ_Envelope *env;
693
680 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 694 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
681 "Sending message ACK to client.\n"); 695 "Sending message ACK to client.\n");
682 696 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_FRAGMENT_ACK);
683 static struct GNUNET_MessageHeader *msg = NULL; 697 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} 698}
692 699
693 700
@@ -983,7 +990,8 @@ handle_cadet_join_request (void *cls,
983 chn->peer = req->peer; 990 chn->peer = req->peer;
984 chn->join_status = JOIN_WAITING; 991 chn->join_status = JOIN_WAITING;
985 992
986 client_send_all (&group_pub_hash, &req->header); 993 client_send_all (&group_pub_hash,
994 GNUNET_MQ_msg_copy (&req->header));
987} 995}
988 996
989 997
@@ -1102,7 +1110,8 @@ handle_cadet_message (void *cls,
1102{ 1110{
1103 struct Channel *chn = cls; 1111 struct Channel *chn = cls;
1104 GNUNET_CADET_receive_done (chn->channel); 1112 GNUNET_CADET_receive_done (chn->channel);
1105 client_send_all (&chn->group_pub_hash, &msg->header); 1113 client_send_all (&chn->group_pub_hash,
1114 GNUNET_MQ_msg_copy (&msg->header));
1106} 1115}
1107 1116
1108 1117
@@ -1153,30 +1162,32 @@ handle_cadet_request (void *cls,
1153{ 1162{
1154 struct Channel *chn = cls; 1163 struct Channel *chn = cls;
1155 GNUNET_CADET_receive_done (chn->channel); 1164 GNUNET_CADET_receive_done (chn->channel);
1156 client_send_origin (&chn->group_pub_hash, &req->header); 1165 client_send_origin (&chn->group_pub_hash,
1166 GNUNET_MQ_msg_copy (&req->header));
1157} 1167}
1158 1168
1159 1169
1160static int 1170// FIXME: do checks in handle_cadet_replay_request
1161check_cadet_replay_request (void *cls, 1171//static int
1162 const struct MulticastReplayRequestMessage *req) 1172//check_cadet_replay_request (void *cls,
1163{ 1173// const struct MulticastReplayRequestMessage *req)
1164 uint16_t size = ntohs (req->header.size); 1174//{
1165 if (size < sizeof (*req)) 1175// uint16_t size = ntohs (req->header.size);
1166 { 1176// if (size < sizeof (*req))
1167 GNUNET_break_op (0); 1177// {
1168 return GNUNET_SYSERR; 1178// GNUNET_break_op (0);
1169 } 1179// return GNUNET_SYSERR;
1170 1180// }
1171 struct Channel *chn = cls; 1181//
1172 if (NULL == chn) 1182// struct Channel *chn = cls;
1173 { 1183// if (NULL == chn)
1174 GNUNET_break_op (0); 1184// {
1175 return GNUNET_SYSERR; 1185// GNUNET_break_op (0);
1176 } 1186// return GNUNET_SYSERR;
1177 1187// }
1178 return GNUNET_OK; 1188//
1179} 1189// return GNUNET_OK;
1190//}
1180 1191
1181 1192
1182/** 1193/**
@@ -1187,6 +1198,7 @@ handle_cadet_replay_request (void *cls,
1187 const struct MulticastReplayRequestMessage *req) 1198 const struct MulticastReplayRequestMessage *req)
1188{ 1199{
1189 struct Channel *chn = cls; 1200 struct Channel *chn = cls;
1201
1190 GNUNET_CADET_receive_done (chn->channel); 1202 GNUNET_CADET_receive_done (chn->channel);
1191 1203
1192 struct MulticastReplayRequestMessage rep = *req; 1204 struct MulticastReplayRequestMessage rep = *req;
@@ -1203,12 +1215,16 @@ handle_cadet_replay_request (void *cls,
1203 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1215 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1204 } 1216 }
1205 struct GNUNET_HashCode key_hash; 1217 struct GNUNET_HashCode key_hash;
1206 replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset, 1218 replay_key_hash (rep.fragment_id,
1207 rep.flags, &key_hash); 1219 rep.message_id,
1220 rep.fragment_offset,
1221 rep.flags,
1222 &key_hash);
1208 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn, 1223 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
1209 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1224 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1210 1225
1211 client_send_random (&chn->group_pub_hash, &rep.header); 1226 client_send_random (&chn->group_pub_hash,
1227 GNUNET_MQ_msg_copy (&rep.header));
1212} 1228}
1213 1229
1214 1230
@@ -1290,10 +1306,10 @@ cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer)
1290 struct MulticastJoinDecisionMessageHeader, 1306 struct MulticastJoinDecisionMessageHeader,
1291 chn), 1307 chn),
1292 1308
1293 GNUNET_MQ_hd_var_size (cadet_replay_request, 1309 GNUNET_MQ_hd_fixed_size (cadet_replay_request,
1294 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 1310 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1295 struct MulticastReplayRequestMessage, 1311 struct MulticastReplayRequestMessage,
1296 chn), 1312 chn),
1297 1313
1298 GNUNET_MQ_hd_var_size (cadet_replay_response, 1314 GNUNET_MQ_hd_var_size (cadet_replay_response,
1299 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 1315 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
@@ -1379,10 +1395,10 @@ handle_client_origin_start (void *cls,
1379 struct MulticastJoinRequestMessage, 1395 struct MulticastJoinRequestMessage,
1380 grp), 1396 grp),
1381 1397
1382 GNUNET_MQ_hd_var_size (cadet_replay_request, 1398 GNUNET_MQ_hd_fixed_size (cadet_replay_request,
1383 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 1399 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1384 struct MulticastReplayRequestMessage, 1400 struct MulticastReplayRequestMessage,
1385 grp), 1401 grp),
1386 1402
1387 GNUNET_MQ_hd_var_size (cadet_replay_response, 1403 GNUNET_MQ_hd_var_size (cadet_replay_response,
1388 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 1404 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
@@ -1494,7 +1510,8 @@ handle_client_member_join (void *cls,
1494 } 1510 }
1495 GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem->pub_key_hash, mem, 1511 GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem->pub_key_hash, mem,
1496 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1512 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1497 1513
1514 // FIXME: should the members hash map have option UNIQUE_FAST?
1498 GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem, 1515 GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem,
1499 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1516 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1500 } 1517 }
@@ -1509,10 +1526,11 @@ handle_client_member_join (void *cls,
1509 1526
1510 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&mem->pub_key); 1527 char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&mem->pub_key);
1511 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1528 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1512 "Client connected to group %s as member %s (%s).\n", 1529 "Client connected to group %s as member %s (%s). size = %d\n",
1513 GNUNET_h2s (&grp->pub_key_hash), 1530 GNUNET_h2s (&grp->pub_key_hash),
1514 GNUNET_h2s2 (&mem->pub_key_hash), 1531 GNUNET_h2s2 (&mem->pub_key_hash),
1515 str); 1532 str,
1533 GNUNET_CONTAINER_multihashmap_size (members));
1516 GNUNET_free (str); 1534 GNUNET_free (str);
1517 1535
1518 if (NULL != mem->join_dcsn) 1536 if (NULL != mem->join_dcsn)
@@ -1567,7 +1585,9 @@ handle_client_member_join (void *cls,
1567 GNUNET_free (mem->join_req); 1585 GNUNET_free (mem->join_req);
1568 mem->join_req = req; 1586 mem->join_req = req;
1569 1587
1570 if (0 == client_send_origin (&grp->pub_key_hash, &mem->join_req->header)) 1588 if (0 ==
1589 client_send_origin (&grp->pub_key_hash,
1590 GNUNET_MQ_msg_copy (&mem->join_req->header)))
1571 { /* No local origins, send to remote origin */ 1591 { /* No local origins, send to remote origin */
1572 cadet_send_join_request (mem); 1592 cadet_send_join_request (mem);
1573 } 1593 }
@@ -1580,7 +1600,7 @@ static void
1580client_send_join_decision (struct Member *mem, 1600client_send_join_decision (struct Member *mem,
1581 const struct MulticastJoinDecisionMessageHeader *hdcsn) 1601 const struct MulticastJoinDecisionMessageHeader *hdcsn)
1582{ 1602{
1583 client_send_group (&mem->group, &hdcsn->header); 1603 client_send_group (&mem->group, GNUNET_MQ_msg_copy (&hdcsn->header));
1584 1604
1585 const struct MulticastJoinDecisionMessage * 1605 const struct MulticastJoinDecisionMessage *
1586 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; 1606 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
@@ -1622,7 +1642,7 @@ handle_client_join_decision (void *cls,
1622 return; 1642 return;
1623 } 1643 }
1624 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1625 "%p Got join decision from client for group %s..\n", 1645 "%p got join decision from client for group %s..\n",
1626 grp, GNUNET_h2s (&grp->pub_key_hash)); 1646 grp, GNUNET_h2s (&grp->pub_key_hash));
1627 1647
1628 struct GNUNET_CONTAINER_MultiHashMap * 1648 struct GNUNET_CONTAINER_MultiHashMap *
@@ -1652,6 +1672,30 @@ handle_client_join_decision (void *cls,
1652} 1672}
1653 1673
1654 1674
1675static void
1676handle_client_part_request (void *cls,
1677 const struct GNUNET_MessageHeader *msg)
1678{
1679 struct Client *c = cls;
1680 struct GNUNET_SERVICE_Client *client = c->client;
1681 struct Group *grp = c->group;
1682 struct GNUNET_MQ_Envelope *env;
1683
1684 if (NULL == grp)
1685 {
1686 GNUNET_break (0);
1687 GNUNET_SERVICE_client_drop (client);
1688 return;
1689 }
1690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1691 "%p got part request from client for group %s.\n",
1692 grp, GNUNET_h2s (&grp->pub_key_hash));
1693 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK);
1694 client_send_group (grp, env);
1695 GNUNET_SERVICE_client_continue (client);
1696}
1697
1698
1655static int 1699static int
1656check_client_multicast_message (void *cls, 1700check_client_multicast_message (void *cls,
1657 const struct GNUNET_MULTICAST_MessageHeader *msg) 1701 const struct GNUNET_MULTICAST_MessageHeader *msg)
@@ -1680,6 +1724,7 @@ handle_client_multicast_message (void *cls,
1680 GNUNET_assert (GNUNET_YES == grp->is_origin); 1724 GNUNET_assert (GNUNET_YES == grp->is_origin);
1681 struct Origin *orig = grp->origin; 1725 struct Origin *orig = grp->origin;
1682 1726
1727 // FIXME: use GNUNET_MQ_msg_copy
1683 /* FIXME: yucky, should use separate message structs for P2P and CS! */ 1728 /* FIXME: yucky, should use separate message structs for P2P and CS! */
1684 struct GNUNET_MULTICAST_MessageHeader * 1729 struct GNUNET_MULTICAST_MessageHeader *
1685 out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (&msg->header); 1730 out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (&msg->header);
@@ -1696,7 +1741,7 @@ handle_client_multicast_message (void *cls,
1696 GNUNET_assert (0); 1741 GNUNET_assert (0);
1697 } 1742 }
1698 1743
1699 client_send_all (&grp->pub_key_hash, &out->header); 1744 client_send_all (&grp->pub_key_hash, GNUNET_MQ_msg_copy (&out->header));
1700 cadet_send_children (&grp->pub_key_hash, &out->header); 1745 cadet_send_children (&grp->pub_key_hash, &out->header);
1701 client_send_ack (&grp->pub_key_hash); 1746 client_send_ack (&grp->pub_key_hash);
1702 GNUNET_free (out); 1747 GNUNET_free (out);
@@ -1751,7 +1796,9 @@ handle_client_multicast_request (void *cls,
1751 } 1796 }
1752 1797
1753 uint8_t send_ack = GNUNET_YES; 1798 uint8_t send_ack = GNUNET_YES;
1754 if (0 == client_send_origin (&grp->pub_key_hash, &out->header)) 1799 if (0 ==
1800 client_send_origin (&grp->pub_key_hash,
1801 GNUNET_MQ_msg_copy (&out->header)))
1755 { /* No local origins, send to remote origin */ 1802 { /* No local origins, send to remote origin */
1756 if (NULL != mem->origin_channel) 1803 if (NULL != mem->origin_channel)
1757 { 1804 {
@@ -1812,7 +1859,9 @@ handle_client_replay_request (void *cls,
1812 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client, 1859 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client,
1813 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1860 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1814 1861
1815 if (0 == client_send_origin (&grp->pub_key_hash, &rep->header)) 1862 if (0 ==
1863 client_send_origin (&grp->pub_key_hash,
1864 GNUNET_MQ_msg_copy (&rep->header)))
1816 { /* No local origin, replay from remote members / origin. */ 1865 { /* No local origin, replay from remote members / origin. */
1817 if (NULL != mem->origin_channel) 1866 if (NULL != mem->origin_channel)
1818 { 1867 {
@@ -1821,6 +1870,7 @@ handle_client_replay_request (void *cls,
1821 else 1870 else
1822 { 1871 {
1823 /* FIXME: not yet connected to origin */ 1872 /* FIXME: not yet connected to origin */
1873 GNUNET_assert (0);
1824 GNUNET_SERVICE_client_drop (client); 1874 GNUNET_SERVICE_client_drop (client);
1825 return; 1875 return;
1826 } 1876 }
@@ -2033,6 +2083,8 @@ client_notify_disconnect (void *cls,
2033 grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member", 2083 grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member",
2034 GNUNET_h2s (&grp->pub_key_hash)); 2084 GNUNET_h2s (&grp->pub_key_hash));
2035 2085
2086 // FIXME (due to protocol change): here we must not remove all clients,
2087 // only the one we were notified about!
2036 struct ClientList *cl = grp->clients_head; 2088 struct ClientList *cl = grp->clients_head;
2037 while (NULL != cl) 2089 while (NULL != cl)
2038 { 2090 {
@@ -2119,6 +2171,10 @@ GNUNET_SERVICE_MAIN
2119 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 2171 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
2120 struct MulticastJoinDecisionMessageHeader, 2172 struct MulticastJoinDecisionMessageHeader,
2121 NULL), 2173 NULL),
2174 GNUNET_MQ_hd_fixed_size (client_part_request,
2175 GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST,
2176 struct GNUNET_MessageHeader,
2177 NULL),
2122 GNUNET_MQ_hd_var_size (client_multicast_message, 2178 GNUNET_MQ_hd_var_size (client_multicast_message,
2123 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 2179 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
2124 struct GNUNET_MULTICAST_MessageHeader, 2180 struct GNUNET_MULTICAST_MessageHeader,
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index a8b1dee40..3c911f48a 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -542,31 +542,12 @@ group_cleanup (struct GNUNET_MULTICAST_Group *grp)
542 542
543 543
544static void 544static void
545group_disconnect (struct GNUNET_MULTICAST_Group *grp, 545handle_group_part_ack (void *cls,
546 GNUNET_ContinuationCallback cb, 546 const struct GNUNET_MessageHeader *msg)
547 void *cls)
548{ 547{
549 grp->is_disconnecting = GNUNET_YES; 548 struct GNUNET_MULTICAST_Group *grp = cls;
550 grp->disconnect_cb = cb;
551 grp->disconnect_cls = cls;
552 549
553 if (NULL != grp->mq) 550 group_cleanup (grp);
554 {
555 struct GNUNET_MQ_Envelope *last = GNUNET_MQ_get_last_envelope (grp->mq);
556 if (NULL != last)
557 {
558 GNUNET_MQ_notify_sent (last,
559 (GNUNET_SCHEDULER_TaskCallback) group_cleanup, grp);
560 }
561 else
562 {
563 group_cleanup (grp);
564 }
565 }
566 else
567 {
568 group_cleanup (grp);
569 }
570} 551}
571 552
572 553
@@ -779,6 +760,10 @@ origin_connect (struct GNUNET_MULTICAST_Origin *orig)
779 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 760 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST,
780 struct MulticastJoinRequestMessage, 761 struct MulticastJoinRequestMessage,
781 grp), 762 grp),
763 GNUNET_MQ_hd_fixed_size (group_part_ack,
764 GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK,
765 struct GNUNET_MessageHeader,
766 grp),
782 GNUNET_MQ_hd_fixed_size (group_replay_request, 767 GNUNET_MQ_hd_fixed_size (group_replay_request,
783 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 768 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
784 struct MulticastReplayRequestMessage, 769 struct MulticastReplayRequestMessage,
@@ -879,8 +864,13 @@ GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *orig,
879 void *stop_cls) 864 void *stop_cls)
880{ 865{
881 struct GNUNET_MULTICAST_Group *grp = &orig->grp; 866 struct GNUNET_MULTICAST_Group *grp = &orig->grp;
867 struct GNUNET_MQ_Envelope *env;
882 868
883 group_disconnect (grp, stop_cb, stop_cls); 869 grp->is_disconnecting = GNUNET_YES;
870 grp->disconnect_cb = stop_cb;
871 grp->disconnect_cls = stop_cls;
872 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST);
873 GNUNET_MQ_send (grp->mq, env);
884} 874}
885 875
886 876
@@ -1065,6 +1055,10 @@ member_connect (struct GNUNET_MULTICAST_Member *mem)
1065 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 1055 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
1066 struct MulticastJoinDecisionMessageHeader, 1056 struct MulticastJoinDecisionMessageHeader,
1067 mem), 1057 mem),
1058 GNUNET_MQ_hd_fixed_size (group_part_ack,
1059 GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK,
1060 struct GNUNET_MessageHeader,
1061 grp),
1068 GNUNET_MQ_hd_fixed_size (group_replay_request, 1062 GNUNET_MQ_hd_fixed_size (group_replay_request,
1069 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 1063 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
1070 struct MulticastReplayRequestMessage, 1064 struct MulticastReplayRequestMessage,
@@ -1198,16 +1192,19 @@ GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *mem,
1198 GNUNET_ContinuationCallback part_cb, 1192 GNUNET_ContinuationCallback part_cb,
1199 void *part_cls) 1193 void *part_cls)
1200{ 1194{
1201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Member parting.\n", mem);
1202 struct GNUNET_MULTICAST_Group *grp = &mem->grp; 1195 struct GNUNET_MULTICAST_Group *grp = &mem->grp;
1196 struct GNUNET_MQ_Envelope *env;
1203 1197
1204 mem->join_dcsn_cb = NULL; 1198 mem->join_dcsn_cb = NULL;
1205 grp->join_req_cb = NULL; 1199 grp->join_req_cb = NULL;
1206 grp->message_cb = NULL; 1200 grp->message_cb = NULL;
1207 grp->replay_msg_cb = NULL; 1201 grp->replay_msg_cb = NULL;
1208 grp->replay_frag_cb = NULL; 1202 grp->replay_frag_cb = NULL;
1209 1203 grp->is_disconnecting = GNUNET_YES;
1210 group_disconnect (grp, part_cb, part_cls); 1204 grp->disconnect_cb = part_cb;
1205 grp->disconnect_cls = part_cls;
1206 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST);
1207 GNUNET_MQ_send (grp->mq, env);
1211} 1208}
1212 1209
1213 1210