aboutsummaryrefslogtreecommitdiff
path: root/src/multicast
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2015-09-26 17:09:57 +0000
committerGabor X Toth <*@tg-x.net>2015-09-26 17:09:57 +0000
commit5a042e00e06de726a21d9db05ddeb2ac16ca7c0c (patch)
tree9b2f504796b72a50d061eb812be4aa87efbf6584 /src/multicast
parent0c5cea1c26efb8b53f643a6ce6b162d9c9fe2b8f (diff)
downloadgnunet-5a042e00e06de726a21d9db05ddeb2ac16ca7c0c.tar.gz
gnunet-5a042e00e06de726a21d9db05ddeb2ac16ca7c0c.zip
multicast: replay
Diffstat (limited to 'src/multicast')
-rw-r--r--src/multicast/gnunet-service-multicast.c562
-rw-r--r--src/multicast/multicast.h114
-rw-r--r--src/multicast/multicast_api.c236
-rw-r--r--src/multicast/test_multicast.c211
4 files changed, 925 insertions, 198 deletions
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index dee573848..e7ee92cdf 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -88,18 +88,33 @@ static struct GNUNET_CONTAINER_MultiHashMap *members;
88static struct GNUNET_CONTAINER_MultiHashMap *group_members; 88static struct GNUNET_CONTAINER_MultiHashMap *group_members;
89 89
90/** 90/**
91 * Incoming CADET channels. 91 * Incoming CADET channels with connected children in the tree.
92 * Group's pub_key_hash -> struct Channel * (multi) 92 * Group's pub_key_hash -> struct Channel * (multi)
93 */ 93 */
94static struct GNUNET_CONTAINER_MultiHashMap *channels_in; 94static struct GNUNET_CONTAINER_MultiHashMap *channels_in;
95 95
96/** 96/**
97 * Outgoing CADET channels. 97 * Outgoing CADET channels connecting to parents in the tree.
98 * Group's pub_key_hash -> struct Channel * (multi) 98 * Group's pub_key_hash -> struct Channel * (multi)
99 */ 99 */
100static struct GNUNET_CONTAINER_MultiHashMap *channels_out; 100static struct GNUNET_CONTAINER_MultiHashMap *channels_out;
101 101
102/** 102/**
103 * Incoming replay requests from CADET.
104 * Group's pub_key_hash ->
105 * H(fragment_id, message_id, fragment_offset, flags) -> struct Channel *
106 */
107static struct GNUNET_CONTAINER_MultiHashMap *replay_req_cadet;
108
109/**
110 * Incoming replay requests from clients.
111 * Group's pub_key_hash ->
112 * H(fragment_id, message_id, fragment_offset, flags) -> struct GNUNET_SERVER_Client *
113 */
114static struct GNUNET_CONTAINER_MultiHashMap *replay_req_client;
115
116
117/**
103 * Join status of a remote peer. 118 * Join status of a remote peer.
104 */ 119 */
105enum JoinStatus 120enum JoinStatus
@@ -294,6 +309,15 @@ struct Member
294}; 309};
295 310
296 311
312struct ReplayRequestKey
313{
314 uint64_t fragment_id;
315 uint64_t message_id;
316 uint64_t fragment_offset;
317 uint64_t flags;
318};
319
320
297/** 321/**
298 * Task run during shutdown. 322 * Task run during shutdown.
299 * 323 *
@@ -375,6 +399,95 @@ cleanup_group (struct Group *grp)
375} 399}
376 400
377 401
402void
403replay_key_hash (uint64_t fragment_id, uint64_t message_id,
404 uint64_t fragment_offset, uint64_t flags,
405 struct GNUNET_HashCode *key_hash)
406{
407 struct ReplayRequestKey key = {
408 .fragment_id = fragment_id,
409 .message_id = message_id,
410 .fragment_offset = fragment_offset,
411 .flags = flags,
412 };
413 GNUNET_CRYPTO_hash (&key, sizeof (key), key_hash);
414}
415
416
417/**
418 * Remove channel from replay request hashmap.
419 *
420 * @param chn
421 * Channel to remove.
422 *
423 * @return #GNUNET_YES if there are more entries to process,
424 * #GNUNET_NO when reached end of hashmap.
425 */
426static int
427replay_req_remove_cadet (struct Channel *chn)
428{
429 struct GNUNET_CONTAINER_MultiHashMap *
430 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
431 &chn->grp->pub_key_hash);
432 if (NULL == grp_replay_req)
433 return GNUNET_NO;
434
435 struct GNUNET_CONTAINER_MultiHashMapIterator *
436 it = GNUNET_CONTAINER_multihashmap_iterator_create (grp_replay_req);
437 struct GNUNET_HashCode key;
438 const struct Channel *c;
439 while (GNUNET_YES
440 == GNUNET_CONTAINER_multihashmap_iterator_next (it, &key,
441 (const void **) &c))
442 {
443 if (c == chn)
444 {
445 GNUNET_CONTAINER_multihashmap_remove (grp_replay_req, &key, chn);
446 return GNUNET_YES;
447 }
448 }
449 GNUNET_CONTAINER_multihashmap_iterator_destroy (it);
450 return GNUNET_NO;
451}
452
453
454/**
455 * Remove client from replay request hashmap.
456 *
457 * @param client
458 * Client to remove.
459 *
460 * @return #GNUNET_YES if there are more entries to process,
461 * #GNUNET_NO when reached end of hashmap.
462 */
463static int
464replay_req_remove_client (struct Group *grp, struct GNUNET_SERVER_Client *client)
465{
466 struct GNUNET_CONTAINER_MultiHashMap *
467 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_client,
468 &grp->pub_key_hash);
469 if (NULL == grp_replay_req)
470 return GNUNET_NO;
471
472 struct GNUNET_CONTAINER_MultiHashMapIterator *
473 it = GNUNET_CONTAINER_multihashmap_iterator_create (grp_replay_req);
474 struct GNUNET_HashCode key;
475 const struct GNUNET_SERVER_Client *c;
476 while (GNUNET_YES
477 == GNUNET_CONTAINER_multihashmap_iterator_next (it, &key,
478 (const void **) &c))
479 {
480 if (c == client)
481 {
482 GNUNET_CONTAINER_multihashmap_remove (replay_req_client, &key, client);
483 return GNUNET_YES;
484 }
485 }
486 GNUNET_CONTAINER_multihashmap_iterator_destroy (it);
487 return GNUNET_NO;
488}
489
490
378/** 491/**
379 * Called whenever a client is disconnected. 492 * Called whenever a client is disconnected.
380 * 493 *
@@ -417,6 +530,8 @@ client_notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
417 cl = cl->next; 530 cl = cl->next;
418 } 531 }
419 532
533 while (GNUNET_YES == replay_req_remove_client (grp, client));
534
420 if (NULL == grp->clients_head) 535 if (NULL == grp->clients_head)
421 { /* Last client disconnected. */ 536 { /* Last client disconnected. */
422#if FIXME 537#if FIXME
@@ -434,14 +549,29 @@ client_notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
434 549
435 550
436/** 551/**
552 * Send message to a client.
553 */
554static void
555client_send (struct GNUNET_SERVER_Client *client,
556 const struct GNUNET_MessageHeader *msg)
557{
558 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
559 "%p Sending message to client.\n", client);
560
561 GNUNET_SERVER_notification_context_add (nc, client);
562 GNUNET_SERVER_notification_context_unicast (nc, client, msg, GNUNET_NO);
563}
564
565
566/**
437 * Send message to all clients connected to the group. 567 * Send message to all clients connected to the group.
438 */ 568 */
439static void 569static void
440client_send_msg (const struct Group *grp, 570client_send_group (const struct Group *grp,
441 const struct GNUNET_MessageHeader *msg) 571 const struct GNUNET_MessageHeader *msg)
442{ 572{
443 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 573 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
444 "%p Sending message to clients.\n", grp); 574 "%p Sending message to all clients of the group.\n", grp);
445 575
446 struct ClientList *cl = grp->clients_head; 576 struct ClientList *cl = grp->clients_head;
447 while (NULL != cl) 577 while (NULL != cl)
@@ -463,7 +593,7 @@ client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
463 const struct GNUNET_MessageHeader *msg = cls; 593 const struct GNUNET_MessageHeader *msg = cls;
464 struct Member *orig = origin; 594 struct Member *orig = origin;
465 595
466 client_send_msg (&orig->grp, msg); 596 client_send_group (&orig->grp, msg);
467 return GNUNET_YES; 597 return GNUNET_YES;
468} 598}
469 599
@@ -480,7 +610,7 @@ client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
480 610
481 if (NULL != mem->join_dcsn) 611 if (NULL != mem->join_dcsn)
482 { /* Only send message to admitted members */ 612 { /* Only send message to admitted members */
483 client_send_msg (&mem->grp, msg); 613 client_send_group (&mem->grp, msg);
484 } 614 }
485 return GNUNET_YES; 615 return GNUNET_YES;
486} 616}
@@ -497,14 +627,32 @@ client_send_all (struct GNUNET_HashCode *pub_key_hash,
497 const struct GNUNET_MessageHeader *msg) 627 const struct GNUNET_MessageHeader *msg)
498{ 628{
499 int n = 0; 629 int n = 0;
500 if (origins != NULL) 630 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
501 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash, 631 client_send_origin_cb,
502 client_send_origin_cb, 632 (void *) msg);
503 (void *) msg); 633 n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash,
504 if (members != NULL) 634 client_send_member_cb,
505 n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash, 635 (void *) msg);
506 client_send_member_cb, 636 return n;
507 (void *) msg); 637}
638
639
640/**
641 * Send message to a random origin client or a random member client.
642 *
643 * @param grp The group to send @a msg to.
644 * @param msg Message to send.
645 */
646static int
647client_send_random (struct GNUNET_HashCode *pub_key_hash,
648 const struct GNUNET_MessageHeader *msg)
649{
650 int n = 0;
651 n = GNUNET_CONTAINER_multihashmap_get_random (origins, client_send_origin_cb,
652 (void *) msg);
653 if (n <= 0)
654 n = GNUNET_CONTAINER_multihashmap_get_random (members, client_send_member_cb,
655 (void *) msg);
508 return n; 656 return n;
509} 657}
510 658
@@ -520,10 +668,9 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash,
520 const struct GNUNET_MessageHeader *msg) 668 const struct GNUNET_MessageHeader *msg)
521{ 669{
522 int n = 0; 670 int n = 0;
523 if (origins != NULL) 671 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
524 n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash, 672 client_send_origin_cb,
525 client_send_origin_cb, 673 (void *) msg);
526 (void *) msg);
527 return n; 674 return n;
528} 675}
529 676
@@ -554,7 +701,7 @@ cadet_notify_transmit_ready (void *cls, size_t buf_size, void *buf)
554 * @param msg Message. 701 * @param msg Message.
555 */ 702 */
556static void 703static void
557cadet_send_msg (struct Channel *chn, const struct GNUNET_MessageHeader *msg) 704cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg)
558{ 705{
559 chn->tmit_handle 706 chn->tmit_handle
560 = GNUNET_CADET_notify_transmit_ready (chn->channel, GNUNET_NO, 707 = GNUNET_CADET_notify_transmit_ready (chn->channel, GNUNET_NO,
@@ -604,14 +751,14 @@ static void
604cadet_send_join_request (struct Member *mem) 751cadet_send_join_request (struct Member *mem)
605{ 752{
606 mem->origin_channel = cadet_channel_create (&mem->grp, &mem->origin); 753 mem->origin_channel = cadet_channel_create (&mem->grp, &mem->origin);
607 cadet_send_msg (mem->origin_channel, &mem->join_req->header); 754 cadet_send_channel (mem->origin_channel, &mem->join_req->header);
608 755
609 uint32_t i; 756 uint32_t i;
610 for (i = 0; i < mem->relay_count; i++) 757 for (i = 0; i < mem->relay_count; i++)
611 { 758 {
612 struct Channel * 759 struct Channel *
613 chn = cadet_channel_create (&mem->grp, &mem->relays[i]); 760 chn = cadet_channel_create (&mem->grp, &mem->relays[i]);
614 cadet_send_msg (chn, &mem->join_req->header); 761 cadet_send_channel (chn, &mem->join_req->header);
615 } 762 }
616} 763}
617 764
@@ -627,7 +774,7 @@ cadet_send_join_decision_cb (void *cls,
627 if (0 == memcmp (&hdcsn->member_key, &chn->member_key, sizeof (chn->member_key)) 774 if (0 == memcmp (&hdcsn->member_key, &chn->member_key, sizeof (chn->member_key))
628 && 0 == memcmp (&hdcsn->peer, &chn->peer, sizeof (chn->peer))) 775 && 0 == memcmp (&hdcsn->peer, &chn->peer, sizeof (chn->peer)))
629 { 776 {
630 cadet_send_msg (chn, &hdcsn->header); 777 cadet_send_channel (chn, &hdcsn->header);
631 return GNUNET_NO; 778 return GNUNET_NO;
632 } 779 }
633 return GNUNET_YES; 780 return GNUNET_YES;
@@ -651,29 +798,47 @@ cadet_send_join_decision (struct Group *grp,
651 * Iterator callback for sending a message to origin clients. 798 * Iterator callback for sending a message to origin clients.
652 */ 799 */
653static int 800static int
654cadet_send_members_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 801cadet_send_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
655 void *channel) 802 void *channel)
656{ 803{
657 const struct GNUNET_MessageHeader *msg = cls; 804 const struct GNUNET_MessageHeader *msg = cls;
658 struct Channel *chn = channel; 805 struct Channel *chn = channel;
659 if (JOIN_ADMITTED == chn->join_status) 806 if (JOIN_ADMITTED == chn->join_status)
660 cadet_send_msg (chn, msg); 807 cadet_send_channel (chn, msg);
661 return GNUNET_YES; 808 return GNUNET_YES;
662} 809}
663 810
664 811
812/**
813 * Send message to all connected children.
814 */
665static int 815static int
666cadet_send_members (struct GNUNET_HashCode *pub_key_hash, 816cadet_send_children (struct GNUNET_HashCode *pub_key_hash,
667 const struct GNUNET_MessageHeader *msg) 817 const struct GNUNET_MessageHeader *msg)
668{ 818{
669 int n = 0; 819 int n = 0;
670 if (channels_in != NULL) 820 if (channels_in != NULL)
671 n += GNUNET_CONTAINER_multihashmap_get_multiple (channels_in, pub_key_hash, 821 n += GNUNET_CONTAINER_multihashmap_get_multiple (channels_in, pub_key_hash,
672 cadet_send_members_cb, 822 cadet_send_cb, (void *) msg);
673 (void *) msg); 823 return n;
824}
825
826
827/**
828 * Send message to all connected parents.
829 */
830static int
831cadet_send_parents (struct GNUNET_HashCode *pub_key_hash,
832 const struct GNUNET_MessageHeader *msg)
833{
834 int n = 0;
835 if (channels_in != NULL)
836 n += GNUNET_CONTAINER_multihashmap_get_multiple (channels_out, pub_key_hash,
837 cadet_send_cb, (void *) msg);
674 return n; 838 return n;
675} 839}
676 840
841
677/** 842/**
678 * Handle a connecting client starting an origin. 843 * Handle a connecting client starting an origin.
679 */ 844 */
@@ -866,7 +1031,7 @@ static void
866client_send_join_decision (struct Member *mem, 1031client_send_join_decision (struct Member *mem,
867 const struct MulticastJoinDecisionMessageHeader *hdcsn) 1032 const struct MulticastJoinDecisionMessageHeader *hdcsn)
868{ 1033{
869 client_send_msg (&mem->grp, &hdcsn->header); 1034 client_send_group (&mem->grp, &hdcsn->header);
870 1035
871 const struct MulticastJoinDecisionMessage * 1036 const struct MulticastJoinDecisionMessage *
872 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; 1037 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
@@ -959,9 +1124,9 @@ client_recv_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
959 } 1124 }
960 GNUNET_assert (GNUNET_YES == grp->is_origin); 1125 GNUNET_assert (GNUNET_YES == grp->is_origin);
961 orig = (struct Origin *) grp; 1126 orig = (struct Origin *) grp;
1127
962 /* FIXME: yucky, should use separate message structs for P2P and CS! */ 1128 /* FIXME: yucky, should use separate message structs for P2P and CS! */
963 out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (m); 1129 out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message (m);
964
965 out->fragment_id = GNUNET_htonll (++orig->max_fragment_id); 1130 out->fragment_id = GNUNET_htonll (++orig->max_fragment_id);
966 out->purpose.size = htonl (ntohs (out->header.size) 1131 out->purpose.size = htonl (ntohs (out->header.size)
967 - sizeof (out->header) 1132 - sizeof (out->header)
@@ -976,7 +1141,7 @@ client_recv_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
976 } 1141 }
977 1142
978 client_send_all (&grp->pub_key_hash, &out->header); 1143 client_send_all (&grp->pub_key_hash, &out->header);
979 cadet_send_members (&grp->pub_key_hash, &out->header); 1144 cadet_send_children (&grp->pub_key_hash, &out->header);
980 GNUNET_free (out); 1145 GNUNET_free (out);
981 1146
982 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1147 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -993,7 +1158,6 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
993 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group); 1158 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
994 struct Member *mem; 1159 struct Member *mem;
995 struct GNUNET_MULTICAST_RequestHeader *out; 1160 struct GNUNET_MULTICAST_RequestHeader *out;
996
997 if (NULL == grp) 1161 if (NULL == grp)
998 { 1162 {
999 GNUNET_break (0); 1163 GNUNET_break (0);
@@ -1002,9 +1166,9 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
1002 } 1166 }
1003 GNUNET_assert (GNUNET_NO == grp->is_origin); 1167 GNUNET_assert (GNUNET_NO == grp->is_origin);
1004 mem = (struct Member *) grp; 1168 mem = (struct Member *) grp;
1169
1005 /* FIXME: yucky, should use separate message structs for P2P and CS! */ 1170 /* FIXME: yucky, should use separate message structs for P2P and CS! */
1006 out = (struct GNUNET_MULTICAST_RequestHeader *) GNUNET_copy_message (m); 1171 out = (struct GNUNET_MULTICAST_RequestHeader *) GNUNET_copy_message (m);
1007
1008 out->member_key = mem->pub_key; 1172 out->member_key = mem->pub_key;
1009 out->fragment_id = GNUNET_ntohll (++mem->max_fragment_id); 1173 out->fragment_id = GNUNET_ntohll (++mem->max_fragment_id);
1010 out->purpose.size = htonl (ntohs (out->header.size) 1174 out->purpose.size = htonl (ntohs (out->header.size)
@@ -1023,7 +1187,7 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
1023 { /* No local origins, send to remote origin */ 1187 { /* No local origins, send to remote origin */
1024 if (NULL != mem->origin_channel) 1188 if (NULL != mem->origin_channel)
1025 { 1189 {
1026 cadet_send_msg (mem->origin_channel, &out->header); 1190 cadet_send_channel (mem->origin_channel, &out->header);
1027 } 1191 }
1028 else 1192 else
1029 { 1193 {
@@ -1039,6 +1203,207 @@ client_recv_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
1039 1203
1040 1204
1041/** 1205/**
1206 * Incoming replay request from a client.
1207 */
1208static void
1209client_recv_replay_request (void *cls, struct GNUNET_SERVER_Client *client,
1210 const struct GNUNET_MessageHeader *m)
1211{
1212 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
1213 struct Member *mem;
1214 if (NULL == grp)
1215 {
1216 GNUNET_break (0);
1217 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1218 return;
1219 }
1220 GNUNET_assert (GNUNET_NO == grp->is_origin);
1221 mem = (struct Member *) grp;
1222
1223 struct GNUNET_CONTAINER_MultiHashMap *
1224 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_client,
1225 &grp->pub_key_hash);
1226 if (NULL == grp_replay_req)
1227 {
1228 grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1229 GNUNET_CONTAINER_multihashmap_put (replay_req_client,
1230 &grp->pub_key_hash, grp_replay_req,
1231 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1232 }
1233 struct MulticastReplayRequestMessage *
1234 rep = (struct MulticastReplayRequestMessage *) m;
1235 struct GNUNET_HashCode key_hash;
1236 replay_key_hash (rep->fragment_id, rep->message_id, rep->fragment_offset,
1237 rep->flags, &key_hash);
1238 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client,
1239 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1240
1241 if (0 == client_send_origin (&grp->pub_key_hash, m))
1242 { /* No local origin, replay from remote members / origin. */
1243 if (NULL != mem->origin_channel)
1244 {
1245 cadet_send_channel (mem->origin_channel, m);
1246 }
1247 else
1248 {
1249 /* FIXME: not yet connected to origin */
1250 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1251 return;
1252 }
1253 }
1254 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1255}
1256
1257
1258static int
1259cadet_send_replay_response_cb (void *cls,
1260 const struct GNUNET_HashCode *key_hash,
1261 void *value)
1262{
1263 struct Channel *chn = value;
1264 struct GNUNET_MessageHeader *msg = cls;
1265
1266 cadet_send_channel (chn, msg);
1267 return GNUNET_OK;
1268}
1269
1270
1271static int
1272client_send_replay_response_cb (void *cls,
1273 const struct GNUNET_HashCode *key_hash,
1274 void *value)
1275{
1276 struct GNUNET_SERVER_Client *client = value;
1277 struct GNUNET_MessageHeader *msg = cls;
1278
1279 client_send (client, msg);
1280 return GNUNET_OK;
1281}
1282
1283
1284/**
1285 * End of replay response from a client.
1286 */
1287static void
1288client_recv_replay_response_end (void *cls, struct GNUNET_SERVER_Client *client,
1289 const struct GNUNET_MessageHeader *m)
1290{
1291 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
1292 if (NULL == grp)
1293 {
1294 GNUNET_break (0);
1295 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1296 return;
1297 }
1298
1299 struct MulticastReplayResponseMessage *
1300 res = (struct MulticastReplayResponseMessage *) m;
1301
1302 struct GNUNET_HashCode key_hash;
1303 replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset,
1304 res->flags, &key_hash);
1305
1306 struct GNUNET_CONTAINER_MultiHashMap *
1307 grp_replay_req_cadet = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
1308 &grp->pub_key_hash);
1309 if (NULL != grp_replay_req_cadet)
1310 {
1311 GNUNET_CONTAINER_multihashmap_remove_all (grp_replay_req_cadet, &key_hash);
1312 }
1313 struct GNUNET_CONTAINER_MultiHashMap *
1314 grp_replay_req_client = GNUNET_CONTAINER_multihashmap_get (replay_req_client,
1315 &grp->pub_key_hash);
1316 if (NULL != grp_replay_req_client)
1317 {
1318 GNUNET_CONTAINER_multihashmap_remove_all (grp_replay_req_client, &key_hash);
1319 }
1320 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1321}
1322
1323
1324/**
1325 * Incoming replay response from a client.
1326 *
1327 * Respond with a multicast message on success, or otherwise with an error code.
1328 */
1329static void
1330client_recv_replay_response (void *cls, struct GNUNET_SERVER_Client *client,
1331 const struct GNUNET_MessageHeader *m)
1332{
1333 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
1334 if (NULL == grp)
1335 {
1336 GNUNET_break (0);
1337 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1338 return;
1339 }
1340
1341 struct MulticastReplayResponseMessage *
1342 res = (struct MulticastReplayResponseMessage *) m;
1343
1344 const struct GNUNET_MessageHeader *msg = m;
1345 if (GNUNET_MULTICAST_REC_OK == res->error_code)
1346 {
1347 msg = (struct GNUNET_MessageHeader *) &res[1];
1348 }
1349
1350 struct GNUNET_HashCode key_hash;
1351 replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset,
1352 res->flags, &key_hash);
1353
1354 struct GNUNET_CONTAINER_MultiHashMap *
1355 grp_replay_req_cadet = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
1356 &grp->pub_key_hash);
1357 if (NULL != grp_replay_req_cadet)
1358 {
1359 GNUNET_CONTAINER_multihashmap_get_multiple (grp_replay_req_cadet, &key_hash,
1360 cadet_send_replay_response_cb,
1361 (void *) msg);
1362 }
1363 if (GNUNET_MULTICAST_REC_OK == res->error_code)
1364 {
1365 struct GNUNET_CONTAINER_MultiHashMap *
1366 grp_replay_req_client = GNUNET_CONTAINER_multihashmap_get (replay_req_client,
1367 &grp->pub_key_hash);
1368 if (NULL != grp_replay_req_client)
1369 {
1370 GNUNET_CONTAINER_multihashmap_get_multiple (grp_replay_req_client, &key_hash,
1371 client_send_replay_response_cb,
1372 (void *) msg);
1373 }
1374 }
1375 else
1376 {
1377 client_recv_replay_response_end (cls, client, m);
1378 return;
1379 }
1380 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1381}
1382
1383
1384/**
1385 * Incoming replay request from a client.
1386 */
1387static void
1388client_recv_replay_request_cancel (void *cls, struct GNUNET_SERVER_Client *client,
1389 const struct GNUNET_MessageHeader *m)
1390{
1391 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
1392}
1393
1394
1395/**
1396 * Incoming replay request from a client.
1397 */
1398static void
1399client_recv_membership_test_result (void *cls, struct GNUNET_SERVER_Client *client,
1400 const struct GNUNET_MessageHeader *m)
1401{
1402 struct Group *grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
1403}
1404
1405
1406/**
1042 * A new client connected. 1407 * A new client connected.
1043 */ 1408 */
1044static void 1409static void
@@ -1053,22 +1418,37 @@ client_notify_connect (void *cls, struct GNUNET_SERVER_Client *client)
1053 * Message handlers for the server. 1418 * Message handlers for the server.
1054 */ 1419 */
1055static const struct GNUNET_SERVER_MessageHandler server_handlers[] = { 1420static const struct GNUNET_SERVER_MessageHandler server_handlers[] = {
1056 { &client_recv_origin_start, NULL, 1421 { client_recv_origin_start, NULL,
1057 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, 1422 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 },
1058 1423
1059 { &client_recv_member_join, NULL, 1424 { client_recv_member_join, NULL,
1060 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, 1425 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 },
1061 1426
1062 { &client_recv_join_decision, NULL, 1427 { client_recv_join_decision, NULL,
1063 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 }, 1428 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 },
1064 1429
1065 { &client_recv_multicast_message, NULL, 1430 { client_recv_multicast_message, NULL,
1066 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, 1431 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
1067 1432
1068 { &client_recv_multicast_request, NULL, 1433 { client_recv_multicast_request, NULL,
1069 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, 1434 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 },
1070 1435
1071 {NULL, NULL, 0, 0} 1436 { client_recv_replay_request, NULL,
1437 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 0 },
1438
1439 { client_recv_replay_request_cancel, NULL,
1440 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST_CANCEL, 0 },
1441
1442 { client_recv_replay_response, NULL,
1443 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 0 },
1444
1445 { client_recv_replay_response_end, NULL,
1446 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END, 0 },
1447
1448 { client_recv_membership_test_result, NULL,
1449 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT, 0 },
1450
1451 { NULL, NULL, 0, 0 }
1072}; 1452};
1073 1453
1074 1454
@@ -1107,6 +1487,9 @@ cadet_notify_channel_end (void *cls,
1107 mem->origin_channel = NULL; 1487 mem->origin_channel = NULL;
1108 } 1488 }
1109 } 1489 }
1490
1491 while (GNUNET_YES == replay_req_remove_cadet (chn));
1492
1110 GNUNET_free (chn); 1493 GNUNET_free (chn);
1111} 1494}
1112 1495
@@ -1320,12 +1703,99 @@ cadet_recv_request (void *cls,
1320 1703
1321 1704
1322/** 1705/**
1706 * Incoming multicast replay request from CADET.
1707 */
1708int
1709cadet_recv_replay_request (void *cls,
1710 struct GNUNET_CADET_Channel *channel,
1711 void **ctx,
1712 const struct GNUNET_MessageHeader *m)
1713{
1714 struct MulticastReplayRequestMessage rep;
1715 uint16_t size = ntohs (m->size);
1716 if (size < sizeof (rep))
1717 {
1718 GNUNET_break_op (0);
1719 return GNUNET_SYSERR;
1720 }
1721 struct Channel *chn = *ctx;
1722
1723 memcpy (&rep, m, sizeof (rep));
1724 memcpy (&rep.member_key, &chn->member_key, sizeof (chn->member_key));
1725
1726 struct GNUNET_CONTAINER_MultiHashMap *
1727 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
1728 &chn->grp->pub_key_hash);
1729 if (NULL == grp_replay_req)
1730 {
1731 grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1732 GNUNET_CONTAINER_multihashmap_put (replay_req_cadet,
1733 &chn->grp->pub_key_hash, grp_replay_req,
1734 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1735 }
1736 struct GNUNET_HashCode key_hash;
1737 replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset,
1738 rep.flags, &key_hash);
1739 GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
1740 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1741
1742 client_send_random (&chn->group_key_hash, &rep.header);
1743 return GNUNET_OK;
1744}
1745
1746
1747/**
1748 * Incoming multicast replay request cancellation from CADET.
1749 */
1750int
1751cadet_recv_replay_request_cancel (void *cls,
1752 struct GNUNET_CADET_Channel *channel,
1753 void **ctx,
1754 const struct GNUNET_MessageHeader *m)
1755{
1756
1757}
1758
1759
1760/**
1761 * Incoming multicast replay response from CADET.
1762 */
1763int
1764cadet_recv_replay_response (void *cls,
1765 struct GNUNET_CADET_Channel *channel,
1766 void **ctx,
1767 const struct GNUNET_MessageHeader *m)
1768{
1769 struct Channel *chn = *ctx;
1770
1771 /* @todo FIXME: got replay error response, send request to other members */
1772
1773 return GNUNET_OK;
1774}
1775
1776
1777/**
1323 * Message handlers for CADET. 1778 * Message handlers for CADET.
1324 */ 1779 */
1325static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { 1780static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
1326 { &cadet_recv_join_request, GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 0 }, 1781 { cadet_recv_join_request,
1327 { &cadet_recv_message, GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, 1782 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 0 },
1328 { &cadet_recv_request, GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, 1783
1784 { cadet_recv_message,
1785 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
1786
1787 { cadet_recv_request,
1788 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 },
1789
1790 { cadet_recv_replay_request,
1791 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 0 },
1792
1793 { cadet_recv_replay_request_cancel,
1794 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST_CANCEL, 0 },
1795
1796 { cadet_recv_replay_response,
1797 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 0 },
1798
1329 { NULL, 0, 0 } 1799 { NULL, 0, 0 }
1330}; 1800};
1331 1801
@@ -1350,6 +1820,8 @@ core_connected_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity)
1350 group_members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 1820 group_members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1351 channels_in = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 1821 channels_in = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1352 channels_out = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 1822 channels_out = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1823 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1824 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1353 1825
1354 cadet = GNUNET_CADET_connect (cfg, NULL, 1826 cadet = GNUNET_CADET_connect (cfg, NULL,
1355 &cadet_notify_channel_new, 1827 &cadet_notify_channel_new,
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h
index 5dc803952..497d67683 100644
--- a/src/multicast/multicast.h
+++ b/src/multicast/multicast.h
@@ -27,6 +27,9 @@
27#ifndef MULTICAST_H 27#ifndef MULTICAST_H
28#define MULTICAST_H 28#define MULTICAST_H
29 29
30#include "platform.h"
31#include "gnunet_multicast_service.h"
32
30GNUNET_NETWORK_STRUCT_BEGIN 33GNUNET_NETWORK_STRUCT_BEGIN
31 34
32 35
@@ -157,49 +160,91 @@ struct MulticastMembershipTestResultMessage
157 160
158 161
159/** 162/**
160 * Message sent from the client to the service to give the service 163 * Message sent from the client to the service OR the service to the
161 * a replayed message. 164 * client asking for a message fragment to be replayed.
162 */ 165 */
163struct MulticastReplayResponseMessage 166struct MulticastReplayRequestMessage
164{ 167{
165 168
166 /** 169 /**
167 * 170 * The message type can be either
171 * #GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST or
172 * #GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST_CANCEL.
168 */ 173 */
169 struct GNUNET_MessageHeader header; 174 struct GNUNET_MessageHeader header;
170 175
171 /** 176 /**
172 * Unique ID that identifies the associated replay session. 177 * S->C: Public key of the member requesting replay.
178 * C->S: Unused.
173 */ 179 */
174 uint32_t uid; 180 struct GNUNET_CRYPTO_EcdsaPublicKey member_key;
175 181
176 /** 182 /**
177 * An `enum GNUNET_MULTICAST_ReplayErrorCode` identifying issues (in NBO). 183 * ID of the message that is being requested.
178 */ 184 */
179 int32_t error_code; 185 uint64_t fragment_id;
180 186
181 /* followed by replayed message */ 187 /**
188 * ID of the message that is being requested.
189 */
190 uint64_t message_id;
191
192 /**
193 * Offset of the fragment that is being requested.
194 */
195 uint64_t fragment_offset;
182 196
197 /**
198 * Additional flags for the request.
199 */
200 uint64_t flags;
201
202 /**
203 * Replay request ID.
204 */
205 uint32_t uid;
183}; 206};
184 207
185 208
186/** 209/**
187 * Message sent from the client to the service to notify the service 210 * Message sent from the client to the service to give the service
188 * about the end of a replay session. 211 * a replayed message.
189 */ 212 */
190struct MulticastReplayEndMessage 213struct MulticastReplayResponseMessage
191{ 214{
192 215
193 /** 216 /**
194 * 217 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE
218 * or GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END
195 */ 219 */
196 struct GNUNET_MessageHeader header; 220 struct GNUNET_MessageHeader header;
197 221
198 /** 222 /**
199 * Unique ID that identifies the associated replay session. 223 * ID of the message that is being requested.
200 */ 224 */
201 uint32_t uid; 225 uint64_t fragment_id;
226
227 /**
228 * ID of the message that is being requested.
229 */
230 uint64_t message_id;
231
232 /**
233 * Offset of the fragment that is being requested.
234 */
235 uint64_t fragment_offset;
202 236
237 /**
238 * Additional flags for the request.
239 */
240 uint64_t flags;
241
242 /**
243 * An `enum GNUNET_MULTICAST_ReplayErrorCode` identifying issues (in NBO).
244 */
245 int32_t error_code;
246
247 /* followed by replayed message */
203}; 248};
204 249
205 250
@@ -253,6 +298,7 @@ struct MulticastMemberJoinMessage
253 /* Followed by struct GNUNET_MessageHeader join_msg */ 298 /* Followed by struct GNUNET_MessageHeader join_msg */
254}; 299};
255 300
301
256#if NOT_USED 302#if NOT_USED
257/** 303/**
258 * Message sent from the client to the service to broadcast to all group 304 * Message sent from the client to the service to broadcast to all group
@@ -323,44 +369,6 @@ struct MulticastJoinMessage
323 369
324 370
325/** 371/**
326 * Message sent from the client to the service OR the service to the
327 * client asking for a message fragment to be replayed.
328 */
329struct MulticastReplayRequestMessage
330{
331
332 /**
333 * The message type can be either
334 * #GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST or
335 * #GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST_CANCEL.
336 */
337 struct GNUNET_MessageHeader header;
338
339 /**
340 * Replay request ID.
341 */
342 uint32_t uid;
343
344 /**
345 * ID of the message that is being requested.
346 */
347 uint64_t message_id;
348
349 /**
350 * Offset of the fragment that is being requested.
351 */
352 uint64_t fragment_offset;
353
354 /**
355 * Additional flags for the request.
356 */
357 uint64_t flags;
358
359};
360
361
362
363/**
364 * Message sent from the client to the service to unicast to the group origin. 372 * Message sent from the client to the service to unicast to the group origin.
365 */ 373 */
366struct MulticastUnicastToOriginMessage 374struct MulticastUnicastToOriginMessage
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index ef4cc73e7..9f0c77f36 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -137,6 +137,11 @@ struct GNUNET_MULTICAST_Member
137 137
138 GNUNET_MULTICAST_JoinDecisionCallback join_dcsn_cb; 138 GNUNET_MULTICAST_JoinDecisionCallback join_dcsn_cb;
139 139
140 /**
141 * Replay fragment -> struct GNUNET_MULTICAST_MemberReplayHandle *
142 */
143 struct GNUNET_CONTAINER_MultiHashMap *replay_reqs;
144
140 uint64_t next_fragment_id; 145 uint64_t next_fragment_id;
141}; 146};
142 147
@@ -176,6 +181,8 @@ struct GNUNET_MULTICAST_MembershipTestHandle
176 */ 181 */
177struct GNUNET_MULTICAST_ReplayHandle 182struct GNUNET_MULTICAST_ReplayHandle
178{ 183{
184 struct GNUNET_MULTICAST_Group *grp;
185 struct MulticastReplayRequestMessage req;
179}; 186};
180 187
181 188
@@ -184,6 +191,9 @@ struct GNUNET_MULTICAST_ReplayHandle
184 */ 191 */
185struct GNUNET_MULTICAST_MemberReplayHandle 192struct GNUNET_MULTICAST_MemberReplayHandle
186{ 193{
194
195 GNUNET_MULTICAST_ResultCallback result_cb;
196 void *result_cls;
187}; 197};
188 198
189 199
@@ -263,11 +273,14 @@ group_recv_message (void *cls,
263 struct GNUNET_MULTICAST_MessageHeader * 273 struct GNUNET_MULTICAST_MessageHeader *
264 mmsg = (struct GNUNET_MULTICAST_MessageHeader *) msg; 274 mmsg = (struct GNUNET_MULTICAST_MessageHeader *) msg;
265 275
276 if (GNUNET_YES == grp->is_disconnecting)
277 return;
278
266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
267 "Calling message callback with a message of size %u.\n", 280 "Calling message callback with a message of size %u.\n",
268 ntohs (mmsg->header.size)); 281 ntohs (mmsg->header.size));
269 282
270 if (GNUNET_YES != grp->is_disconnecting && NULL != grp->message_cb) 283 if (NULL != grp->message_cb)
271 grp->message_cb (grp->cb_cls, mmsg); 284 grp->message_cb (grp->cb_cls, mmsg);
272} 285}
273 286
@@ -297,6 +310,73 @@ origin_recv_request (void *cls,
297 310
298 311
299/** 312/**
313 * Receive multicast replay request from service.
314 */
315static void
316group_recv_replay_request (void *cls,
317 struct GNUNET_CLIENT_MANAGER_Connection *client,
318 const struct GNUNET_MessageHeader *msg)
319{
320 struct GNUNET_MULTICAST_Group *
321 grp = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*grp));
322 struct MulticastReplayRequestMessage *
323 rep = (struct MulticastReplayRequestMessage *) msg;
324
325 if (GNUNET_YES == grp->is_disconnecting)
326 return;
327
328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got replay request.\n");
329
330 if (0 != rep->fragment_id)
331 {
332 if (NULL != grp->replay_frag_cb)
333 {
334 struct GNUNET_MULTICAST_ReplayHandle * rh = GNUNET_malloc (sizeof (*rh));
335 rh->grp = grp;
336 rh->req = *rep;
337 grp->replay_frag_cb (grp->cb_cls, &rep->member_key,
338 GNUNET_ntohll (rep->fragment_id),
339 GNUNET_ntohll (rep->flags), rh);
340 }
341 }
342 else if (0 != rep->message_id)
343 {
344 if (NULL != grp->replay_msg_cb)
345 {
346 struct GNUNET_MULTICAST_ReplayHandle * rh = GNUNET_malloc (sizeof (*rh));
347 rh->grp = grp;
348 rh->req = *rep;
349 grp->replay_msg_cb (grp->cb_cls, &rep->member_key,
350 GNUNET_ntohll (rep->message_id),
351 GNUNET_ntohll (rep->fragment_offset),
352 GNUNET_ntohll (rep->flags), rh);
353 }
354 }
355}
356
357
358/**
359 * Receive multicast replay request from service.
360 */
361static void
362member_recv_replay_response (void *cls,
363 struct GNUNET_CLIENT_MANAGER_Connection *client,
364 const struct GNUNET_MessageHeader *msg)
365{
366 struct GNUNET_MULTICAST_Group *grp;
367 struct GNUNET_MULTICAST_Member *
368 mem = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*grp));
369 grp = &mem->grp;
370 struct MulticastReplayResponseMessage *
371 res = (struct MulticastReplayResponseMessage *) msg;
372
373 if (GNUNET_YES == grp->is_disconnecting)
374 return;
375
376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got replay response.\n");
377}
378
379/**
300 * Member receives join decision. 380 * Member receives join decision.
301 */ 381 */
302static void 382static void
@@ -369,20 +449,24 @@ member_recv_join_decision (void *cls,
369 */ 449 */
370static struct GNUNET_CLIENT_MANAGER_MessageHandler origin_handlers[] = 450static struct GNUNET_CLIENT_MANAGER_MessageHandler origin_handlers[] =
371{ 451{
372 { &group_recv_disconnect, NULL, 0, 0, GNUNET_NO }, 452 { group_recv_disconnect, NULL, 0, 0, GNUNET_NO },
373 453
374 { &group_recv_message, NULL, 454 { group_recv_message, NULL,
375 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 455 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
376 sizeof (struct GNUNET_MULTICAST_MessageHeader), GNUNET_YES }, 456 sizeof (struct GNUNET_MULTICAST_MessageHeader), GNUNET_YES },
377 457
378 { &origin_recv_request, NULL, 458 { origin_recv_request, NULL,
379 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 459 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST,
380 sizeof (struct GNUNET_MULTICAST_RequestHeader), GNUNET_YES }, 460 sizeof (struct GNUNET_MULTICAST_RequestHeader), GNUNET_YES },
381 461
382 { &group_recv_join_request, NULL, 462 { group_recv_join_request, NULL,
383 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 463 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST,
384 sizeof (struct MulticastJoinRequestMessage), GNUNET_YES }, 464 sizeof (struct MulticastJoinRequestMessage), GNUNET_YES },
385 465
466 { group_recv_replay_request, NULL,
467 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
468 sizeof (struct MulticastReplayRequestMessage), GNUNET_NO },
469
386 { NULL, NULL, 0, 0, GNUNET_NO } 470 { NULL, NULL, 0, 0, GNUNET_NO }
387}; 471};
388 472
@@ -392,20 +476,28 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler origin_handlers[] =
392 */ 476 */
393static struct GNUNET_CLIENT_MANAGER_MessageHandler member_handlers[] = 477static struct GNUNET_CLIENT_MANAGER_MessageHandler member_handlers[] =
394{ 478{
395 { &group_recv_disconnect, NULL, 0, 0, GNUNET_NO }, 479 { group_recv_disconnect, NULL, 0, 0, GNUNET_NO },
396 480
397 { &group_recv_message, NULL, 481 { group_recv_message, NULL,
398 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 482 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
399 sizeof (struct GNUNET_MULTICAST_MessageHeader), GNUNET_YES }, 483 sizeof (struct GNUNET_MULTICAST_MessageHeader), GNUNET_YES },
400 484
401 { &group_recv_join_request, NULL, 485 { group_recv_join_request, NULL,
402 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 486 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST,
403 sizeof (struct MulticastJoinRequestMessage), GNUNET_YES }, 487 sizeof (struct MulticastJoinRequestMessage), GNUNET_YES },
404 488
405 { &member_recv_join_decision, NULL, 489 { member_recv_join_decision, NULL,
406 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 490 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
407 sizeof (struct MulticastJoinDecisionMessage), GNUNET_YES }, 491 sizeof (struct MulticastJoinDecisionMessage), GNUNET_YES },
408 492
493 { group_recv_replay_request, NULL,
494 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
495 sizeof (struct MulticastReplayRequestMessage), GNUNET_NO },
496
497 { member_recv_replay_response, NULL,
498 GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
499 sizeof (struct MulticastReplayRequestMessage), GNUNET_NO },
500
409 { NULL, NULL, 0, 0, GNUNET_NO } 501 { NULL, NULL, 0, 0, GNUNET_NO }
410}; 502};
411 503
@@ -514,15 +606,45 @@ GNUNET_MULTICAST_membership_test_result (struct GNUNET_MULTICAST_MembershipTestH
514/** 606/**
515 * Replay a message fragment for the multicast group. 607 * Replay a message fragment for the multicast group.
516 * 608 *
517 * @param rh Replay handle identifying which replay operation was requested. 609 * @param rh
518 * @param msg Replayed message fragment, NULL if unknown/error. 610 * Replay handle identifying which replay operation was requested.
519 * @param ec Error code. 611 * @param msg
612 * Replayed message fragment, NULL if not found / an error occurred.
613 * @param ec
614 * Error code. See enum GNUNET_MULTICAST_ReplayErrorCode
615 * If not #GNUNET_MULTICAST_REC_OK, the replay handle is invalidated.
520 */ 616 */
521void 617void
522GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh, 618GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh,
523 const struct GNUNET_MessageHeader *msg, 619 const struct GNUNET_MessageHeader *msg,
524 enum GNUNET_MULTICAST_ReplayErrorCode ec) 620 enum GNUNET_MULTICAST_ReplayErrorCode ec)
525{ 621{
622 uint8_t msg_size = (NULL != msg) ? ntohs (msg->size) : 0;
623 struct MulticastReplayResponseMessage *
624 res = GNUNET_malloc (sizeof (*res) + msg_size);
625 *res = (struct MulticastReplayResponseMessage) {
626 .header = {
627 .type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE),
628 .size = htons (sizeof (*res) + msg_size),
629 },
630 .fragment_id = rh->req.fragment_id,
631 .message_id = rh->req.message_id,
632 .fragment_offset = rh->req.fragment_offset,
633 .flags = rh->req.flags,
634 .error_code = htonl (ec),
635 };
636
637 if (GNUNET_MULTICAST_REC_OK == ec)
638 {
639 GNUNET_assert (NULL != msg);
640 memcpy (&res[1], msg, msg_size);
641 }
642
643 GNUNET_CLIENT_MANAGER_transmit (rh->grp->client, &res->header);
644 GNUNET_free (res);
645
646 if (GNUNET_MULTICAST_REC_OK != ec)
647 GNUNET_free (rh);
526} 648}
527 649
528 650
@@ -536,6 +658,19 @@ GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh,
536void 658void
537GNUNET_MULTICAST_replay_response_end (struct GNUNET_MULTICAST_ReplayHandle *rh) 659GNUNET_MULTICAST_replay_response_end (struct GNUNET_MULTICAST_ReplayHandle *rh)
538{ 660{
661 struct MulticastReplayResponseMessage end = {
662 .header = {
663 .type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END),
664 .size = htons (sizeof (end)),
665 },
666 .fragment_id = rh->req.fragment_id,
667 .message_id = rh->req.message_id,
668 .fragment_offset = rh->req.fragment_offset,
669 .flags = rh->req.flags,
670 };
671
672 GNUNET_CLIENT_MANAGER_transmit (rh->grp->client, &end.header);
673 GNUNET_free (rh);
539} 674}
540 675
541 676
@@ -827,6 +962,7 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
827 grp->join_req_cb = join_request_cb; 962 grp->join_req_cb = join_request_cb;
828 grp->member_test_cb = member_test_cb; 963 grp->member_test_cb = member_test_cb;
829 grp->replay_frag_cb = replay_frag_cb; 964 grp->replay_frag_cb = replay_frag_cb;
965 grp->replay_msg_cb = replay_msg_cb;
830 grp->message_cb = message_cb; 966 grp->message_cb = message_cb;
831 grp->cb_cls = cls; 967 grp->cb_cls = cls;
832 968
@@ -864,26 +1000,55 @@ GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *mem,
864} 1000}
865 1001
866 1002
1003void
1004member_replay_request (struct GNUNET_MULTICAST_Member *mem,
1005 uint64_t fragment_id,
1006 uint64_t message_id,
1007 uint64_t fragment_offset,
1008 uint64_t flags)
1009{
1010 struct MulticastReplayRequestMessage rep = {
1011 .header = {
1012 .type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST),
1013 .size = htons (sizeof (rep)),
1014 },
1015 .fragment_id = GNUNET_htonll (fragment_id),
1016 .message_id = GNUNET_htonll (message_id),
1017 .fragment_offset = GNUNET_htonll (fragment_offset),
1018 .flags = GNUNET_htonll (flags),
1019 };
1020 GNUNET_CLIENT_MANAGER_transmit (mem->grp.client, &rep.header);
1021}
1022
1023
867/** 1024/**
868 * Request a fragment to be replayed by fragment ID. 1025 * Request a fragment to be replayed by fragment ID.
869 * 1026 *
870 * Useful if messages below the @e max_known_fragment_id given when joining are 1027 * Useful if messages below the @e max_known_fragment_id given when joining are
871 * needed and not known to the client. 1028 * needed and not known to the client.
872 * 1029 *
873 * @param member Membership handle. 1030 * @param member
874 * @param fragment_id ID of a message fragment that this client would like to 1031 * Membership handle.
875 see replayed. 1032 * @param fragment_id
876 * @param flags Additional flags for the replay request. It is used and defined 1033 * ID of a message fragment that this client would like to see replayed.
877 * by the replay callback. FIXME: which replay callback? FIXME: use enum? 1034 * @param flags
878 * FIXME: why not pass reply cb here? 1035 * Additional flags for the replay request.
879 * @return Replay request handle, NULL on error. 1036 * It is used and defined by GNUNET_MULTICAST_ReplayFragmentCallback
1037 * @param result_cb
1038 * Function to call when the replayed message fragment arrives.
1039 * @param result_cls
1040 * Closure for @a result_cb.
1041 *
1042 * @return Replay request handle.
880 */ 1043 */
881struct GNUNET_MULTICAST_MemberReplayHandle * 1044struct GNUNET_MULTICAST_MemberReplayHandle *
882GNUNET_MULTICAST_member_replay_fragment (struct GNUNET_MULTICAST_Member *member, 1045GNUNET_MULTICAST_member_replay_fragment (struct GNUNET_MULTICAST_Member *mem,
883 uint64_t fragment_id, 1046 uint64_t fragment_id,
884 uint64_t flags) 1047 uint64_t flags,
1048 GNUNET_MULTICAST_ResultCallback result_cb,
1049 void *result_cls)
885{ 1050{
886 return NULL; 1051 member_replay_request (mem, fragment_id, 0, 0, flags);
887} 1052}
888 1053
889 1054
@@ -893,24 +1058,31 @@ GNUNET_MULTICAST_member_replay_fragment (struct GNUNET_MULTICAST_Member *member,
893 * Useful if messages below the @e max_known_fragment_id given when joining are 1058 * Useful if messages below the @e max_known_fragment_id given when joining are
894 * needed and not known to the client. 1059 * needed and not known to the client.
895 * 1060 *
896 * @param member Membership handle. 1061 * @param member
897 * @param message_id ID of the message this client would like to see replayed. 1062 * Membership handle.
898 * @param fragment_offset Offset of the fragment within the message to replay. 1063 * @param message_id
899 * @param flags Additional flags for the replay request. It is used & defined 1064 * ID of the message this client would like to see replayed.
900 * by the replay callback. 1065 * @param fragment_offset
901 * @param result_cb Function to be called for the replayed message. 1066 * Offset of the fragment within the message to replay.
902 * @param result_cb_cls Closure for @a result_cb. 1067 * @param flags
1068 * Additional flags for the replay request.
1069 * It is used & defined by GNUNET_MULTICAST_ReplayMessageCallback
1070 * @param result_cb
1071 * Function to call for each replayed message fragment.
1072 * @param result_cls
1073 * Closure for @a result_cb.
1074 *
903 * @return Replay request handle, NULL on error. 1075 * @return Replay request handle, NULL on error.
904 */ 1076 */
905struct GNUNET_MULTICAST_MemberReplayHandle * 1077struct GNUNET_MULTICAST_MemberReplayHandle *
906GNUNET_MULTICAST_member_replay_message (struct GNUNET_MULTICAST_Member *member, 1078GNUNET_MULTICAST_member_replay_message (struct GNUNET_MULTICAST_Member *mem,
907 uint64_t message_id, 1079 uint64_t message_id,
908 uint64_t fragment_offset, 1080 uint64_t fragment_offset,
909 uint64_t flags, 1081 uint64_t flags,
910 GNUNET_MULTICAST_ResultCallback result_cb, 1082 GNUNET_MULTICAST_ResultCallback result_cb,
911 void *result_cb_cls) 1083 void *result_cls)
912{ 1084{
913 return NULL; 1085 member_replay_request (mem, 0, message_id, fragment_offset, flags);
914} 1086}
915 1087
916 1088
diff --git a/src/multicast/test_multicast.c b/src/multicast/test_multicast.c
index 528033452..d9b9ce0df 100644
--- a/src/multicast/test_multicast.c
+++ b/src/multicast/test_multicast.c
@@ -84,17 +84,21 @@ struct GNUNET_MessageHeader *join_req, *join_resp;
84 84
85enum 85enum
86{ 86{
87 TEST_NONE = 0, 87 TEST_NONE = 0,
88 TEST_ORIGIN_START = 1, 88 TEST_ORIGIN_START = 1,
89 TEST_MEMBER_JOIN_REFUSE = 2, 89 TEST_MEMBER_JOIN_REFUSE = 2,
90 TEST_MEMBER_JOIN_ADMIT = 3, 90 TEST_MEMBER_JOIN_ADMIT = 3,
91 TEST_ORIGIN_TO_ALL = 4, 91 TEST_ORIGIN_TO_ALL = 4,
92 TEST_ORIGIN_TO_ALL_RECV = 5, 92 TEST_ORIGIN_TO_ALL_RECV = 5,
93 TEST_MEMBER_TO_ORIGIN = 6, 93 TEST_MEMBER_TO_ORIGIN = 6,
94 TEST_MEMBER_PART = 7, 94 TEST_MEMBER_REPLAY_ERROR = 7,
95 TEST_ORIGIN_STOP = 8, 95 TEST_MEMBER_REPLAY_OK = 8,
96 TEST_MEMBER_PART = 9,
97 TEST_ORIGIN_STOP = 10,
96} test; 98} test;
97 99
100uint64_t replay_fragment_id;
101uint64_t replay_flags;
98 102
99static void 103static void
100member_join (int t); 104member_join (int t);
@@ -230,56 +234,6 @@ tmit_notify (void *cls, size_t *data_size, void *data)
230 234
231 235
232static void 236static void
233origin_recv_replay_msg (void *cls,
234 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
235 uint64_t message_id,
236 uint64_t fragment_offset,
237 uint64_t flags,
238 struct GNUNET_MULTICAST_ReplayHandle *rh)
239{
240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
241 "Test #%u: origin_recv_replay_msg()\n", test);
242}
243
244
245static void
246member_recv_replay_msg (void *cls,
247 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
248 uint64_t message_id,
249 uint64_t fragment_offset,
250 uint64_t flags,
251 struct GNUNET_MULTICAST_ReplayHandle *rh)
252{
253 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
254 "Test #%u: member_recv_replay_msg()\n", test);
255}
256
257
258static void
259origin_recv_replay_frag (void *cls,
260 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
261 uint64_t fragment_id,
262 uint64_t flags,
263 struct GNUNET_MULTICAST_ReplayHandle *rh)
264{
265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
266 "Test #%u: origin_recv_replay_frag()\n", test);
267}
268
269
270static void
271member_recv_replay_frag (void *cls,
272 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
273 uint64_t fragment_id,
274 uint64_t flags,
275 struct GNUNET_MULTICAST_ReplayHandle *rh)
276{
277 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
278 "Test #%u: member_recv_replay_frag()\n", test);
279}
280
281
282static void
283origin_recv_membership_test (void *cls, 237origin_recv_membership_test (void *cls,
284 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key, 238 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
285 uint64_t message_id, 239 uint64_t message_id,
@@ -339,6 +293,7 @@ member_parted (void *cls)
339{ 293{
340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
341 "Test #%u: member_parted()\n", test); 295 "Test #%u: member_parted()\n", test);
296 member = NULL;
342 297
343 switch (test) 298 switch (test)
344 { 299 {
@@ -359,20 +314,135 @@ member_parted (void *cls)
359 314
360 315
361static void 316static void
317schedule_member_part (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
318{
319 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
320 "Test #%u: schedule_member_part()\n", test);
321 GNUNET_MULTICAST_member_part (member, member_parted, NULL);
322}
323
324
325static void
362member_part () 326member_part ()
363{ 327{
364 test = TEST_MEMBER_PART; 328 test = TEST_MEMBER_PART;
365 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 329 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
366 "Test #%u: member_part()\n", test); 330 "Test #%u: member_part()\n", test);
367 GNUNET_MULTICAST_member_part (member, member_parted, NULL); 331 GNUNET_SCHEDULER_add_now (schedule_member_part, NULL);
368 member = NULL;
369} 332}
370 333
371 334
372static void 335static void
373schedule_member_part (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 336member_replay_ok ()
374{ 337{
375 GNUNET_MULTICAST_member_part (member, member_parted, NULL); 338 test = TEST_MEMBER_REPLAY_OK;
339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
340 "Test #%u: member_replay_ok()\n", test);
341 replay_fragment_id = 1;
342 replay_flags = 1 | 1<<11;
343 GNUNET_MULTICAST_member_replay_fragment (member, replay_fragment_id,
344 replay_flags, NULL, NULL);
345}
346
347
348static void
349member_replay_error ()
350{
351 test = TEST_MEMBER_REPLAY_ERROR;
352 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
353 "Test #%u: member_replay_error()\n", test);
354 replay_fragment_id = 1234;
355 replay_flags = 11 | 1<<11;
356 GNUNET_MULTICAST_member_replay_fragment (member, replay_fragment_id,
357 replay_flags, NULL, NULL);
358}
359
360
361static void
362origin_recv_replay_msg (void *cls,
363 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
364 uint64_t message_id,
365 uint64_t fragment_offset,
366 uint64_t flags,
367 struct GNUNET_MULTICAST_ReplayHandle *rh)
368{
369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
370 "Test #%u: origin_recv_replay_msg()\n", test);
371 GNUNET_assert (0);
372}
373
374
375static void
376member_recv_replay_msg (void *cls,
377 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
378 uint64_t message_id,
379 uint64_t fragment_offset,
380 uint64_t flags,
381 struct GNUNET_MULTICAST_ReplayHandle *rh)
382{
383 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
384 "Test #%u: member_recv_replay_msg()\n", test);
385 GNUNET_assert (0);
386}
387
388
389static void
390origin_recv_replay_frag (void *cls,
391 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
392 uint64_t fragment_id,
393 uint64_t flags,
394 struct GNUNET_MULTICAST_ReplayHandle *rh)
395{
396 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
397 "Test #%u: origin_recv_replay_frag()"
398 " - fragment_id=%" PRIu64 " flags=%" PRIu64 "\n",
399 test, fragment_id, flags);
400 GNUNET_assert (replay_fragment_id == fragment_id && replay_flags == flags);
401 switch (test)
402 {
403 case TEST_MEMBER_REPLAY_ERROR:
404 GNUNET_MULTICAST_replay_response (rh, NULL, GNUNET_SYSERR);
405 member_replay_ok ();
406 break;
407
408 case TEST_MEMBER_REPLAY_OK:
409 {
410 struct GNUNET_MULTICAST_MessageHeader mmsg = {
411 .header = {
412 .type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE),
413 .size = htons (sizeof (mmsg)),
414 },
415 .fragment_id = GNUNET_htonll (1),
416 .message_id = GNUNET_htonll (1),
417 .fragment_offset = 0,
418 .group_generation = GNUNET_htonll (1),
419 .flags = 0,
420 };
421 member_cls.n = 0;
422 member_cls.msgs_expected = 1;
423 GNUNET_MULTICAST_replay_response (rh, &mmsg.header, GNUNET_MULTICAST_REC_OK);
424 GNUNET_MULTICAST_replay_response_end (rh);
425 break;
426 }
427
428 default:
429 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
430 "Invalid test #%d in origin_recv_replay_frag()\n", test);
431 GNUNET_assert (0);
432 }
433}
434
435
436static void
437member_recv_replay_frag (void *cls,
438 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
439 uint64_t fragment_id,
440 uint64_t flags,
441 struct GNUNET_MULTICAST_ReplayHandle *rh)
442{
443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
444 "Test #%u: member_recv_replay_frag()\n", test);
445 GNUNET_assert (0);
376} 446}
377 447
378 448
@@ -385,14 +455,14 @@ origin_recv_request (void *cls,
385 "Test #%u: origin_recv_request()\n", test); 455 "Test #%u: origin_recv_request()\n", test);
386 if (++ocls->n != ocls->msgs_expected) 456 if (++ocls->n != ocls->msgs_expected)
387 return; 457 return;
388 458
389 GNUNET_assert (0 == memcmp (&req->member_key, 459 GNUNET_assert (0 == memcmp (&req->member_key,
390 &member_pub_key, sizeof (member_pub_key))); 460 &member_pub_key, sizeof (member_pub_key)));
391 461
392 462
393 // FIXME: check message content 463 // FIXME: check message content
394 464
395 member_part (); 465 member_replay_error ();
396} 466}
397 467
398 468
@@ -437,6 +507,11 @@ member_recv_message (void *cls,
437 member_to_origin (); 507 member_to_origin ();
438 break; 508 break;
439 509
510 case TEST_MEMBER_REPLAY_OK:
511 GNUNET_assert (replay_fragment_id == GNUNET_ntohll (msg->fragment_id));
512 member_part ();
513 break;
514
440 default: 515 default:
441 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 516 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
442 "Invalid test #%d in origin_recv_message()\n", test); 517 "Invalid test #%d in origin_recv_message()\n", test);
@@ -516,7 +591,7 @@ member_recv_join_decision (void *cls,
516 GNUNET_assert (0 == relay_count); 591 GNUNET_assert (0 == relay_count);
517 GNUNET_SCHEDULER_add_now (schedule_member_part, NULL); 592 GNUNET_SCHEDULER_add_now (schedule_member_part, NULL);
518 break; 593 break;
519 594
520 case TEST_MEMBER_JOIN_ADMIT: 595 case TEST_MEMBER_JOIN_ADMIT:
521 GNUNET_assert (1 == relay_count); 596 GNUNET_assert (1 == relay_count);
522 GNUNET_assert (0 == memcmp (relays, &this_peer, sizeof (this_peer))); 597 GNUNET_assert (0 == memcmp (relays, &this_peer, sizeof (this_peer)));
@@ -551,13 +626,13 @@ origin_recv_join_request (void *cls,
551 join_resp->size = htons (sizeof (join_resp) + data_size); 626 join_resp->size = htons (sizeof (join_resp) + data_size);
552 join_resp->type = htons (456); 627 join_resp->type = htons (456);
553 memcpy (&join_resp[1], data, data_size); 628 memcpy (&join_resp[1], data, data_size);
554 629
555 switch (test) 630 switch (test)
556 { 631 {
557 case TEST_MEMBER_JOIN_REFUSE: 632 case TEST_MEMBER_JOIN_REFUSE:
558 GNUNET_MULTICAST_join_decision (jh, GNUNET_NO, 0, NULL, join_resp); 633 GNUNET_MULTICAST_join_decision (jh, GNUNET_NO, 0, NULL, join_resp);
559 break; 634 break;
560 635
561 case TEST_MEMBER_JOIN_ADMIT: 636 case TEST_MEMBER_JOIN_ADMIT:
562 GNUNET_MULTICAST_join_decision (jh, GNUNET_YES, 1, &this_peer, join_resp); 637 GNUNET_MULTICAST_join_decision (jh, GNUNET_YES, 1, &this_peer, join_resp);
563 break; 638 break;