diff options
Diffstat (limited to 'src/multicast/gnunet-service-multicast.c')
-rw-r--r-- | src/multicast/gnunet-service-multicast.c | 248 |
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, | |||
365 | static void | 366 | static void |
366 | shutdown_task (void *cls) | 367 | shutdown_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 | */ |
555 | static void | 563 | static void |
556 | client_send_group (const struct Group *grp, | 564 | client_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 | */ | ||
585 | static void | ||
586 | client_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 | */ |
578 | static int | 597 | static int |
579 | client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, | 598 | client_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 | |||
594 | client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, | 613 | client_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 | */ |
616 | static int | 635 | static int |
617 | client_send_all (struct GNUNET_HashCode *pub_key_hash, | 636 | client_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 | */ |
637 | static int | 657 | static int |
638 | client_send_random (struct GNUNET_HashCode *pub_key_hash, | 658 | client_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 | */ |
659 | static int | 679 | static int |
660 | client_send_origin (struct GNUNET_HashCode *pub_key_hash, | 680 | client_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, | |||
677 | static void | 697 | static void |
678 | client_send_ack (struct GNUNET_HashCode *pub_key_hash) | 698 | client_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 | ||
1160 | static int | 1178 | // FIXME: do checks in handle_cadet_replay_request |
1161 | check_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 | |||
1580 | client_send_join_decision (struct Member *mem, | 1610 | client_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 | ||
1686 | static void | ||
1687 | handle_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 | |||
1655 | static int | 1712 | static int |
1656 | check_client_multicast_message (void *cls, | 1713 | check_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 | |||
1667 | handle_client_multicast_message (void *cls, | 1724 | handle_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, | |||
2103 | GNUNET_SERVICE_MAIN | 2167 | GNUNET_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, |