aboutsummaryrefslogtreecommitdiff
path: root/src/multicast
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2014-05-26 22:16:05 +0000
committerGabor X Toth <*@tg-x.net>2014-05-26 22:16:05 +0000
commit83495695331fcfa8824d7a6d407b82cfcfc8b13c (patch)
tree2d2a7717d81890f5142da9561bccf9e164b1deee /src/multicast
parent1cfab01aaea932539c39dcb2118ec4d6c6d44381 (diff)
downloadgnunet-83495695331fcfa8824d7a6d407b82cfcfc8b13c.tar.gz
gnunet-83495695331fcfa8824d7a6d407b82cfcfc8b13c.zip
psyc, multicast: join decision, tests
Diffstat (limited to 'src/multicast')
-rw-r--r--src/multicast/Makefile.am2
-rw-r--r--src/multicast/gnunet-service-multicast.c160
-rw-r--r--src/multicast/multicast.h51
-rw-r--r--src/multicast/multicast_api.c120
4 files changed, 196 insertions, 137 deletions
diff --git a/src/multicast/Makefile.am b/src/multicast/Makefile.am
index b2c1702e4..8ccc7b88a 100644
--- a/src/multicast/Makefile.am
+++ b/src/multicast/Makefile.am
@@ -46,10 +46,12 @@ gnunet_service_multicast_SOURCES = \
46 gnunet-service-multicast.c 46 gnunet-service-multicast.c
47gnunet_service_multicast_LDADD = \ 47gnunet_service_multicast_LDADD = \
48 $(top_builddir)/src/util/libgnunetutil.la \ 48 $(top_builddir)/src/util/libgnunetutil.la \
49 $(top_builddir)/src/core/libgnunetcore.la \
49 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 50 $(top_builddir)/src/statistics/libgnunetstatistics.la \
50 $(GN_LIBINTL) 51 $(GN_LIBINTL)
51gnunet_service_multicast_DEPENDENCIES = \ 52gnunet_service_multicast_DEPENDENCIES = \
52 $(top_builddir)/src/util/libgnunetutil.la \ 53 $(top_builddir)/src/util/libgnunetutil.la \
54 $(top_builddir)/src/core/libgnunetcore.la \
53 $(top_builddir)/src/statistics/libgnunetstatistics.la 55 $(top_builddir)/src/statistics/libgnunetstatistics.la
54 56
55 57
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index d412d3f8e..5421c1b2b 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -27,6 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h" 28#include "gnunet_signatures.h"
29#include "gnunet_statistics_service.h" 29#include "gnunet_statistics_service.h"
30#include "gnunet_core_service.h"
30#include "gnunet_multicast_service.h" 31#include "gnunet_multicast_service.h"
31#include "multicast.h" 32#include "multicast.h"
32 33
@@ -36,6 +37,22 @@
36static const struct GNUNET_CONFIGURATION_Handle *cfg; 37static const struct GNUNET_CONFIGURATION_Handle *cfg;
37 38
38/** 39/**
40 * Server handle.
41 */
42static struct GNUNET_SERVER_Handle *server;
43
44/**
45 * Core handle.
46 * Only used during initialization.
47 */
48static struct GNUNET_CORE_Handle *core;
49
50/**
51 * Identity of this peer.
52 */
53static struct GNUNET_PeerIdentity this_peer;
54
55/**
39 * Handle to the statistics service. 56 * Handle to the statistics service.
40 */ 57 */
41static struct GNUNET_STATISTICS_Handle *stats; 58static struct GNUNET_STATISTICS_Handle *stats;
@@ -62,7 +79,6 @@ static struct GNUNET_CONTAINER_MultiHashMap *members;
62 */ 79 */
63static struct GNUNET_CONTAINER_MultiHashMap *group_members; 80static struct GNUNET_CONTAINER_MultiHashMap *group_members;
64 81
65
66/** 82/**
67 * List of connected clients. 83 * List of connected clients.
68 */ 84 */
@@ -147,7 +163,7 @@ struct Member
147 /** 163 /**
148 * Join request sent to the origin / members. 164 * Join request sent to the origin / members.
149 */ 165 */
150 struct MulticastJoinRequestMessage *join_request; 166 struct MulticastJoinRequestMessage *join_req;
151 167
152 /** 168 /**
153 * Join decision sent in reply to our request. 169 * Join decision sent in reply to our request.
@@ -155,7 +171,7 @@ struct Member
155 * Only a positive decision is stored here, in case of a negative decision the 171 * Only a positive decision is stored here, in case of a negative decision the
156 * client is disconnected. 172 * client is disconnected.
157 */ 173 */
158 struct MulticastJoinDecisionMessage *join_decision; 174 struct MulticastJoinDecisionMessageHeader *join_dcsn;
159 175
160 /** 176 /**
161 * Last request fragment ID sent to the origin. 177 * Last request fragment ID sent to the origin.
@@ -171,9 +187,19 @@ struct Member
171 * @param tc unused 187 * @param tc unused
172 */ 188 */
173static void 189static void
174cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 190shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
175{ 191{
176 /* FIXME: do clean up here */ 192 if (NULL != core)
193 {
194 GNUNET_CORE_disconnect (core);
195 core = NULL;
196 }
197 if (NULL != stats)
198 {
199 GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
200 stats = NULL;
201 }
202 /* FIXME: do more clean up here */
177} 203}
178 204
179/** 205/**
@@ -206,8 +232,11 @@ cleanup_member (struct Member *mem)
206 grp_mem); 232 grp_mem);
207 GNUNET_CONTAINER_multihashmap_destroy (grp_mem); 233 GNUNET_CONTAINER_multihashmap_destroy (grp_mem);
208 } 234 }
209 if (NULL != mem->join_decision) 235 if (NULL != mem->join_dcsn)
210 GNUNET_free (mem->join_decision); 236 {
237 GNUNET_free (mem->join_dcsn);
238 mem->join_dcsn = NULL;
239 }
211 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem); 240 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem);
212} 241}
213 242
@@ -329,7 +358,7 @@ member_message_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
329 const struct GNUNET_MessageHeader *msg = cls; 358 const struct GNUNET_MessageHeader *msg = cls;
330 struct Member *mem = member; 359 struct Member *mem = member;
331 360
332 if (NULL != mem->join_decision) 361 if (NULL != mem->join_dcsn)
333 { /* Only send message to admitted members */ 362 { /* Only send message to admitted members */
334 message_to_clients (&mem->grp, msg); 363 message_to_clients (&mem->grp, msg);
335 } 364 }
@@ -374,7 +403,7 @@ message_to_origin (struct Group *grp, const struct GNUNET_MessageHeader *msg)
374 * Handle a connecting client starting an origin. 403 * Handle a connecting client starting an origin.
375 */ 404 */
376static void 405static void
377handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client, 406client_origin_start (void *cls, struct GNUNET_SERVER_Client *client,
378 const struct GNUNET_MessageHeader *m) 407 const struct GNUNET_MessageHeader *m)
379{ 408{
380 const struct MulticastOriginStartMessage * 409 const struct MulticastOriginStartMessage *
@@ -424,8 +453,8 @@ handle_origin_start (void *cls, struct GNUNET_SERVER_Client *client,
424 * Handle a connecting client joining a group. 453 * Handle a connecting client joining a group.
425 */ 454 */
426static void 455static void
427handle_member_join (void *cls, struct GNUNET_SERVER_Client *client, 456client_member_join (void *cls, struct GNUNET_SERVER_Client *client,
428 const struct GNUNET_MessageHeader *m) 457 const struct GNUNET_MessageHeader *m)
429{ 458{
430 const struct MulticastMemberJoinMessage * 459 const struct MulticastMemberJoinMessage *
431 msg = (const struct MulticastMemberJoinMessage *) m; 460 msg = (const struct MulticastMemberJoinMessage *) m;
@@ -487,16 +516,16 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
487 516
488 GNUNET_SERVER_client_set_user_context (client, grp); 517 GNUNET_SERVER_client_set_user_context (client, grp);
489 518
490 if (NULL != mem->join_decision) 519 if (NULL != mem->join_dcsn)
491 { /* Already got a join decision, send it to client. */ 520 { /* Already got a join decision, send it to client. */
492 GNUNET_SERVER_notification_context_add (nc, client); 521 GNUNET_SERVER_notification_context_add (nc, client);
493 GNUNET_SERVER_notification_context_unicast (nc, client, 522 GNUNET_SERVER_notification_context_unicast (nc, client,
494 (struct GNUNET_MessageHeader *) 523 (struct GNUNET_MessageHeader *)
495 mem->join_decision, 524 mem->join_dcsn,
496 GNUNET_NO); 525 GNUNET_NO);
497 } 526 }
498 else if (grp->clients_head == grp->clients_tail) 527 else if (grp->clients_head == grp->clients_tail)
499 { /* First client, send join request. */ 528 { /* First client of the group, send join request. */
500 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1]; 529 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1];
501 uint32_t relay_count = ntohs (msg->relay_count); 530 uint32_t relay_count = ntohs (msg->relay_count);
502 uint16_t relay_size = relay_count * sizeof (*relays); 531 uint16_t relay_size = relay_count * sizeof (*relays);
@@ -515,6 +544,7 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
515 req->header.size = htons (sizeof (*req) + join_msg_size); 544 req->header.size = htons (sizeof (*req) + join_msg_size);
516 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST); 545 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST);
517 req->group_key = grp->pub_key; 546 req->group_key = grp->pub_key;
547 req->member_peer = this_peer;
518 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key); 548 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key);
519 if (0 < join_msg_size) 549 if (0 < join_msg_size)
520 memcpy (&req[1], join_msg, join_msg_size); 550 memcpy (&req[1], join_msg, join_msg_size);
@@ -531,14 +561,14 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
531 GNUNET_assert (0); 561 GNUNET_assert (0);
532 } 562 }
533 563
534 if (NULL != mem->join_request) 564 if (NULL != mem->join_req)
535 GNUNET_free (mem->join_request); 565 GNUNET_free (mem->join_req);
536 mem->join_request = req; 566 mem->join_req = req;
537 567
538 if (GNUNET_YES 568 if (GNUNET_YES
539 == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash)) 569 == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash))
540 { /* Local origin */ 570 { /* Local origin */
541 message_to_origin (grp, (struct GNUNET_MessageHeader *) mem->join_request); 571 message_to_origin (grp, (struct GNUNET_MessageHeader *) mem->join_req);
542 } 572 }
543 else 573 else
544 { 574 {
@@ -553,34 +583,15 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
553 * Join decision from client. 583 * Join decision from client.
554 */ 584 */
555static void 585static void
556handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client, 586client_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
557 const struct GNUNET_MessageHeader *m) 587 const struct GNUNET_MessageHeader *m)
558{ 588{
559 struct Group * 589 struct Group *
560 grp = GNUNET_SERVER_client_get_user_context (client, struct Group); 590 grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
561 const struct MulticastClientJoinDecisionMessage * 591 const struct MulticastJoinDecisionMessageHeader *
562 cl_dcsn = (const struct MulticastClientJoinDecisionMessage *) m; 592 hdcsn = (const struct MulticastJoinDecisionMessageHeader *) m;
563 593 const struct MulticastJoinDecisionMessage *
564 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &cl_dcsn[1]; 594 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
565 uint32_t relay_count = ntohs (cl_dcsn->relay_count);
566 uint16_t relay_size = relay_count * sizeof (*relays);
567
568 struct GNUNET_MessageHeader *join_msg = NULL;
569 uint16_t join_msg_size = 0;
570 if (sizeof (*cl_dcsn) + relay_size + sizeof (*m) <= ntohs (m->size))
571 {
572 join_msg = (struct GNUNET_MessageHeader *)
573 (((char *) &cl_dcsn[1]) + relay_size);
574 join_msg_size = ntohs (join_msg->size);
575 }
576
577 int keep_dcsn = GNUNET_NO;
578 struct MulticastJoinDecisionMessage *
579 dcsn = GNUNET_malloc (sizeof (*dcsn) + join_msg_size);
580 dcsn->header.size = htons (sizeof (*dcsn) + join_msg_size);
581 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
582 dcsn->is_admitted = cl_dcsn->is_admitted;
583 memcpy (&dcsn[1], join_msg, join_msg_size);
584 595
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
586 "%p Got join decision from client for group %s..\n", 597 "%p Got join decision from client for group %s..\n",
@@ -595,7 +606,7 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
595 if (NULL != grp_mem) 606 if (NULL != grp_mem)
596 { 607 {
597 struct GNUNET_HashCode member_key_hash; 608 struct GNUNET_HashCode member_key_hash;
598 GNUNET_CRYPTO_hash (&cl_dcsn->member_key, sizeof (cl_dcsn->member_key), 609 GNUNET_CRYPTO_hash (&hdcsn->member_key, sizeof (hdcsn->member_key),
599 &member_key_hash); 610 &member_key_hash);
600 struct Member * 611 struct Member *
601 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &member_key_hash); 612 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &member_key_hash);
@@ -604,19 +615,21 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
604 grp, GNUNET_h2s (&member_key_hash), mem); 615 grp, GNUNET_h2s (&member_key_hash), mem);
605 if (NULL != mem) 616 if (NULL != mem)
606 { 617 {
607 message_to_clients (grp, (struct GNUNET_MessageHeader *) dcsn); 618 message_to_clients (&mem->grp, (struct GNUNET_MessageHeader *) hdcsn);
608 if (GNUNET_YES == dcsn->is_admitted) 619 if (GNUNET_YES == ntohl (dcsn->is_admitted))
609 { /* Member admitted, store join_decision. */ 620 { /* Member admitted, store join_decision. */
610 mem->join_decision = dcsn; 621 uint16_t dcsn_size = ntohs (dcsn->header.size);
611 keep_dcsn = GNUNET_YES; 622 mem->join_dcsn = GNUNET_malloc (dcsn_size);
623 memcpy (mem->join_dcsn, dcsn, dcsn_size);
612 } 624 }
613 else 625 else
614 { /* Refused entry, disconnect clients. */ 626 { /* Refused entry, disconnect clients. */
615 struct ClientList *cl = mem->grp.clients_head; 627 struct ClientList *cl = mem->grp.clients_head;
616 while (NULL != cl) 628 while (NULL != cl)
617 { 629 {
618 GNUNET_SERVER_client_disconnect (cl->client); 630 struct GNUNET_SERVER_Client *client = cl->client;
619 cl = cl->next; 631 cl = cl->next;
632 GNUNET_SERVER_client_disconnect (client);
620 } 633 }
621 } 634 }
622 } 635 }
@@ -624,10 +637,8 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
624 } 637 }
625 else 638 else
626 { 639 {
627 /* FIXME: send join decision to remote peers */ 640 /* FIXME: send join decision to hdcsn->peer */
628 } 641 }
629 if (GNUNET_NO == keep_dcsn)
630 GNUNET_free (dcsn);
631 GNUNET_SERVER_receive_done (client, GNUNET_OK); 642 GNUNET_SERVER_receive_done (client, GNUNET_OK);
632} 643}
633 644
@@ -635,7 +646,7 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
635 * Incoming message from a client. 646 * Incoming message from a client.
636 */ 647 */
637static void 648static void
638handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client, 649client_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
639 const struct GNUNET_MessageHeader *m) 650 const struct GNUNET_MessageHeader *m)
640{ 651{
641 struct Group * 652 struct Group *
@@ -670,7 +681,7 @@ handle_multicast_message (void *cls, struct GNUNET_SERVER_Client *client,
670 * Incoming request from a client. 681 * Incoming request from a client.
671 */ 682 */
672static void 683static void
673handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client, 684client_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
674 const struct GNUNET_MessageHeader *m) 685 const struct GNUNET_MessageHeader *m)
675{ 686{
676 struct Group * 687 struct Group *
@@ -708,37 +719,34 @@ handle_multicast_request (void *cls, struct GNUNET_SERVER_Client *client,
708 GNUNET_SERVER_receive_done (client, GNUNET_OK); 719 GNUNET_SERVER_receive_done (client, GNUNET_OK);
709} 720}
710 721
722
711/** 723/**
712 * Process multicast requests. 724 * Core connected.
713 *
714 * @param cls closure
715 * @param server the initialized server
716 * @param cfg configuration to use
717 */ 725 */
718static void 726static void
719run (void *cls, struct GNUNET_SERVER_Handle *server, 727core_connected_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity)
720 const struct GNUNET_CONFIGURATION_Handle *c)
721{ 728{
729 this_peer = *my_identity;
730
722 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 731 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
723 { &handle_origin_start, NULL, 732 { &client_origin_start, NULL,
724 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 }, 733 GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START, 0 },
725 734
726 { &handle_member_join, NULL, 735 { &client_member_join, NULL,
727 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, 736 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 },
728 737
729 { &handle_join_decision, NULL, 738 { &client_join_decision, NULL,
730 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 }, 739 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 },
731 740
732 { &handle_multicast_message, NULL, 741 { &client_multicast_message, NULL,
733 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, 742 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
734 743
735 { &handle_multicast_request, NULL, 744 { &client_multicast_request, NULL,
736 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, 745 GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 },
737 746
738 {NULL, NULL, 0, 0} 747 {NULL, NULL, 0, 0}
739 }; 748 };
740 749
741 cfg = c;
742 stats = GNUNET_STATISTICS_create ("multicast", cfg); 750 stats = GNUNET_STATISTICS_create ("multicast", cfg);
743 origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 751 origins = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
744 members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 752 members = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
@@ -747,12 +755,30 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
747 755
748 GNUNET_SERVER_add_handlers (server, handlers); 756 GNUNET_SERVER_add_handlers (server, handlers);
749 GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); 757 GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
750 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, 758 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
751 NULL); 759 NULL);
752} 760}
753 761
754 762
755/** 763/**
764 * Service started.
765 *
766 * @param cls closure
767 * @param server the initialized server
768 * @param cfg configuration to use
769 */
770static void
771run (void *cls, struct GNUNET_SERVER_Handle *srv,
772 const struct GNUNET_CONFIGURATION_Handle *c)
773{
774 cfg = c;
775 server = srv;
776 core = GNUNET_CORE_connect (cfg, NULL, core_connected_cb, NULL, NULL,
777 NULL, GNUNET_NO, NULL, GNUNET_NO, NULL);
778}
779
780
781/**
756 * The main function for the multicast service. 782 * The main function for the multicast service.
757 * 783 *
758 * @param argc number of arguments from the command line 784 * @param argc number of arguments from the command line
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h
index 85c5714e6..76492e868 100644
--- a/src/multicast/multicast.h
+++ b/src/multicast/multicast.h
@@ -77,7 +77,7 @@ struct MulticastJoinRequestMessage
77 77
78 78
79/** 79/**
80 * Header of a join decision sent to a remote peer. 80 * Header of a join decision message sent to a peer requesting join.
81 */ 81 */
82struct MulticastJoinDecisionMessage 82struct MulticastJoinDecisionMessage
83{ 83{
@@ -87,19 +87,28 @@ struct MulticastJoinDecisionMessage
87 struct GNUNET_MessageHeader header; 87 struct GNUNET_MessageHeader header;
88 88
89 /** 89 /**
90 * #GNUNET_YES if the peer was admitted. 90 * #GNUNET_YES if the peer was admitted
91 * #GNUNET_NO if entry was refused,
92 * #GNUNET_SYSERR if the request could not be answered.
91 */ 93 */
92 uint8_t is_admitted; 94 int32_t is_admitted;
95
96 /**
97 * Number of relays given.
98 */
99 uint32_t relay_count;
100
101 /* Followed by relay_count peer identities */
93 102
94 /* Followed by the join response message */ 103 /* Followed by the join response message */
95}; 104};
96 105
97 106
98/** 107/**
99 * Message sent from the client to the service to notify the service 108 * Header added to a struct MulticastJoinDecisionMessage
100 * about a join decision. 109 * when sent between the client and service.
101 */ 110 */
102struct MulticastClientJoinDecisionMessage 111struct MulticastJoinDecisionMessageHeader
103{ 112{
104 /** 113 /**
105 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION 114 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION
@@ -107,29 +116,18 @@ struct MulticastClientJoinDecisionMessage
107 struct GNUNET_MessageHeader header; 116 struct GNUNET_MessageHeader header;
108 117
109 /** 118 /**
110 * Number of relays given. 119 * C->S: Peer to send the join decision to.
120 * S->C: Peer we received the join decision from.
111 */ 121 */
112 uint32_t relay_count; 122 struct GNUNET_PeerIdentity peer;
113 123
114 /** 124 /**
115 * Public key of the joining member. 125 * C->S: Public key of the member requesting join.
126 * S->C: Unused.
116 */ 127 */
117 struct GNUNET_CRYPTO_EddsaPublicKey member_key; 128 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
118 129
119 /** 130 /* Followed by struct MulticastJoinDecisionMessage */
120 * Peer identity of the joining member.
121 */
122 struct GNUNET_PeerIdentity member_peer;
123
124 /**
125 * #GNUNET_YES if the peer was admitted.
126 */
127 uint8_t is_admitted;
128
129 /* Followed by relay_count peer identities */
130
131 /* Followed by the join response message */
132
133}; 131};
134 132
135 133
@@ -139,7 +137,6 @@ struct MulticastClientJoinDecisionMessage
139 */ 137 */
140struct MulticastMembershipTestResultMessage 138struct MulticastMembershipTestResultMessage
141{ 139{
142
143 /** 140 /**
144 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT 141 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT
145 */ 142 */
@@ -151,11 +148,11 @@ struct MulticastMembershipTestResultMessage
151 uint32_t uid; 148 uint32_t uid;
152 149
153 /** 150 /**
154 * #GNUNET_YES if the peer is a member, #GNUNET_NO if peer was not a member, 151 * #GNUNET_YES if the peer is a member
155 * #GNUNET_SYSERR if we cannot answer the test. 152 * #GNUNET_NO if peer is not a member,
153 * #GNUNET_SYSERR if the test could not be answered.
156 */ 154 */
157 int32_t is_admitted; 155 int32_t is_admitted;
158
159}; 156};
160 157
161 158
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index 501ff4b70..e568e77ee 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -132,7 +132,7 @@ struct GNUNET_MULTICAST_Group
132 struct GNUNET_CRYPTO_EddsaPublicKey pub_key; 132 struct GNUNET_CRYPTO_EddsaPublicKey pub_key;
133 struct GNUNET_HashCode pub_key_hash; 133 struct GNUNET_HashCode pub_key_hash;
134 134
135 GNUNET_MULTICAST_JoinCallback join_cb; 135 GNUNET_MULTICAST_JoinRequestCallback join_req_cb;
136 GNUNET_MULTICAST_MembershipTestCallback member_test_cb; 136 GNUNET_MULTICAST_MembershipTestCallback member_test_cb;
137 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb; 137 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb;
138 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb; 138 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb;
@@ -177,10 +177,7 @@ struct GNUNET_MULTICAST_Member
177 struct GNUNET_MULTICAST_Group grp; 177 struct GNUNET_MULTICAST_Group grp;
178 struct GNUNET_MULTICAST_MemberTransmitHandle tmit; 178 struct GNUNET_MULTICAST_MemberTransmitHandle tmit;
179 179
180 struct GNUNET_CRYPTO_EddsaPrivateKey priv_key; 180 GNUNET_MULTICAST_JoinDecisionCallback join_dcsn_cb;
181 struct GNUNET_PeerIdentity origin;
182 struct GNUNET_PeerIdentity relays;
183 uint32_t relay_count;
184 181
185 uint64_t next_fragment_id; 182 uint64_t next_fragment_id;
186}; 183};
@@ -197,12 +194,12 @@ struct GNUNET_MULTICAST_JoinHandle
197 struct GNUNET_MULTICAST_Group *group; 194 struct GNUNET_MULTICAST_Group *group;
198 195
199 /** 196 /**
200 * Public key of the joining member. 197 * Public key of the member requesting join.
201 */ 198 */
202 struct GNUNET_CRYPTO_EddsaPublicKey member_key; 199 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
203 200
204 /** 201 /**
205 * Peer identity of the joining member. 202 * Peer identity of the member requesting join.
206 */ 203 */
207 struct GNUNET_PeerIdentity member_peer; 204 struct GNUNET_PeerIdentity member_peer;
208}; 205};
@@ -476,8 +473,9 @@ request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, void *origin)
476 "Calling request callback for a request of type %u and size %u.\n", 473 "Calling request callback for a request of type %u and size %u.\n",
477 ntohs (req->header.type), ntohs (req->header.size)); 474 ntohs (req->header.type), ntohs (req->header.size));
478 475
479 orig->request_cb (orig->grp.cb_cls, &req->member_key, 476 if (NULL != orig->request_cb)
480 (const struct GNUNET_MessageHeader *) req, 0); 477 orig->request_cb (orig->grp.cb_cls, &req->member_key,
478 (const struct GNUNET_MessageHeader *) req, 0);
481 return GNUNET_YES; 479 return GNUNET_YES;
482} 480}
483 481
@@ -501,7 +499,8 @@ join_request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
501 if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size)) 499 if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size))
502 msg = (const struct GNUNET_MessageHeader *) &req[1]; 500 msg = (const struct GNUNET_MessageHeader *) &req[1];
503 501
504 grp->join_cb (grp->cb_cls, &req->member_key, msg, jh); 502 if (NULL != grp->join_req_cb)
503 grp->join_req_cb (grp->cb_cls, &req->member_key, msg, jh);
505 return GNUNET_YES; 504 return GNUNET_YES;
506} 505}
507 506
@@ -513,15 +512,44 @@ static int
513join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 512join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
514 void *member) 513 void *member)
515{ 514{
516 const struct MulticastJoinDecisionMessage *dcsn = cls; 515 const struct MulticastJoinDecisionMessageHeader *hdcsn = cls;
516 const struct MulticastJoinDecisionMessage *
517 dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
517 struct GNUNET_MULTICAST_Member *mem = member; 518 struct GNUNET_MULTICAST_Member *mem = member;
518 struct GNUNET_MULTICAST_Group *grp = &mem->grp; 519 struct GNUNET_MULTICAST_Group *grp = &mem->grp;
519 520
520 const struct GNUNET_MessageHeader *msg = NULL; 521 uint16_t dcsn_size = ntohs (dcsn->header.size);
521 if (sizeof (*dcsn) + sizeof (*msg) <= ntohs (dcsn->header.size)) 522 int is_admitted = ntohl (dcsn->is_admitted);
522 msg = (const struct GNUNET_MessageHeader *) &dcsn[1]; 523
524 const struct GNUNET_MessageHeader *join_resp = NULL;
525 uint16_t join_resp_size = 0;
526
527 uint16_t relay_count = ntohl (dcsn->relay_count);
528 const struct GNUNET_PeerIdentity *relays = NULL;
529 uint16_t relay_size = relay_count * sizeof (*relays);
530 if (0 < relay_count && dcsn_size < sizeof (*dcsn) + relay_size)
531 relays = (struct GNUNET_PeerIdentity *) &dcsn[1];
532
533 if (sizeof (*dcsn) + relay_size + sizeof (*join_resp) <= dcsn_size)
534 {
535 join_resp = (const struct GNUNET_MessageHeader *) &dcsn[1];
536 join_resp_size = ntohs (join_resp->size);
537 }
538 if (dcsn_size < sizeof (*dcsn) + relay_size + join_resp_size)
539 {
540 LOG (GNUNET_ERROR_TYPE_DEBUG,
541 "Received invalid join decision message from multicast.\n");
542 GNUNET_break_op (0);
543 is_admitted = GNUNET_SYSERR;
544 }
545
546 if (NULL != mem->join_dcsn_cb)
547 mem->join_dcsn_cb (grp->cb_cls, is_admitted, &hdcsn->peer,
548 relay_count, relays, join_resp);
549
550 if (GNUNET_YES != is_admitted)
551 GNUNET_MULTICAST_member_part (mem);
523 552
524 // FIXME: grp->join_decision_cb (grp->cb_cls, msg);
525 return GNUNET_YES; 553 return GNUNET_YES;
526} 554}
527 555
@@ -599,7 +627,6 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
599 GNUNET_break (0); 627 GNUNET_break (0);
600 break; 628 break;
601 } 629 }
602
603 if (NULL != origins) 630 if (NULL != origins)
604 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, 631 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash,
605 request_cb, (void *) msg); 632 request_cb, (void *) msg);
@@ -615,9 +642,11 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
615 break; 642 break;
616 643
617 case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION: 644 case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION:
618 if (NULL != origins) 645 if (GNUNET_NO != grp->is_origin)
619 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash, 646 {
620 join_decision_cb, (void *) msg); 647 GNUNET_break (0);
648 break;
649 }
621 if (NULL != members) 650 if (NULL != members)
622 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, 651 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash,
623 join_decision_cb, (void *) msg); 652 join_decision_cb, (void *) msg);
@@ -636,11 +665,12 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
636 * Function to call with the decision made for a join request. 665 * Function to call with the decision made for a join request.
637 * 666 *
638 * Must be called once and only once in response to an invocation of the 667 * Must be called once and only once in response to an invocation of the
639 * #GNUNET_MULTICAST_JoinCallback. 668 * #GNUNET_MULTICAST_JoinRequestCallback.
640 * 669 *
641 * @param jh Join request handle. 670 * @param jh Join request handle.
642 * @param is_admitted #GNUNET_YES if joining is approved, 671 * @param is_admitted #GNUNET_YES if the join is approved,
643 * #GNUNET_NO if it is disapproved 672 * #GNUNET_NO if it is disapproved,
673 * #GNUNET_SYSERR if we cannot answer the request.
644 * @param relay_count Number of relays given. 674 * @param relay_count Number of relays given.
645 * @param relays Array of suggested peers that might be useful relays to use 675 * @param relays Array of suggested peers that might be useful relays to use
646 * when joining the multicast group (essentially a list of peers that 676 * when joining the multicast group (essentially a list of peers that
@@ -657,25 +687,31 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
657struct GNUNET_MULTICAST_ReplayHandle * 687struct GNUNET_MULTICAST_ReplayHandle *
658GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh, 688GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
659 int is_admitted, 689 int is_admitted,
660 unsigned int relay_count, 690 uint16_t relay_count,
661 const struct GNUNET_PeerIdentity *relays, 691 const struct GNUNET_PeerIdentity *relays,
662 const struct GNUNET_MessageHeader *join_resp) 692 const struct GNUNET_MessageHeader *join_resp)
663{ 693{
664 struct GNUNET_MULTICAST_Group *grp = jh->group; 694 struct GNUNET_MULTICAST_Group *grp = jh->group;
665 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0; 695 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0;
666 uint16_t relay_size = relay_count * sizeof (*relays); 696 uint16_t relay_size = relay_count * sizeof (*relays);
667 struct MulticastClientJoinDecisionMessage * dcsn; 697 struct MulticastJoinDecisionMessageHeader * hdcsn;
698 struct MulticastJoinDecisionMessage *dcsn;
668 struct MessageQueue * 699 struct MessageQueue *
669 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn) 700 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*hdcsn) + sizeof (*dcsn)
670 + relay_size + join_resp_size); 701 + relay_size + join_resp_size);
671 702
672 dcsn = (struct MulticastClientJoinDecisionMessage *) &mq[1]; 703 hdcsn = (struct MulticastJoinDecisionMessageHeader *) &mq[1];
704 hdcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
705 hdcsn->header.size = htons (sizeof (*hdcsn) + sizeof (*dcsn)
706 + relay_size + join_resp_size);
707 hdcsn->member_key = jh->member_key;
708 hdcsn->peer = jh->member_peer;
709
710 dcsn = (struct MulticastJoinDecisionMessage *) &hdcsn[1];
673 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION); 711 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
674 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size); 712 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size);
675 dcsn->member_key = jh->member_key; 713 dcsn->is_admitted = htonl (is_admitted);
676 dcsn->member_peer = jh->member_peer; 714 dcsn->relay_count = htonl (relay_count);
677 dcsn->is_admitted = is_admitted;
678 dcsn->relay_count = relay_count;
679 if (0 < relay_size) 715 if (0 < relay_size)
680 memcpy (&dcsn[1], relays, relay_size); 716 memcpy (&dcsn[1], relays, relay_size);
681 if (0 < join_resp_size) 717 if (0 < join_resp_size)
@@ -763,7 +799,7 @@ GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
763 * multicast session; public key is used to identify the multicast group; 799 * multicast session; public key is used to identify the multicast group;
764 * @param max_fragment_id Maximum fragment ID already sent to the group. 800 * @param max_fragment_id Maximum fragment ID already sent to the group.
765 * 0 for a new group. 801 * 0 for a new group.
766 * @param join_cb Function called to approve / disapprove joining of a peer. 802 * @param join_request_cb Function called to approve / disapprove joining of a peer.
767 * @param member_test_cb Function multicast can use to test group membership. 803 * @param member_test_cb Function multicast can use to test group membership.
768 * @param replay_frag_cb Function that can be called to replay a message fragment. 804 * @param replay_frag_cb Function that can be called to replay a message fragment.
769 * @param replay_msg_cb Function that can be called to replay a message. 805 * @param replay_msg_cb Function that can be called to replay a message.
@@ -779,7 +815,7 @@ struct GNUNET_MULTICAST_Origin *
779GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 815GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
780 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key, 816 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key,
781 uint64_t max_fragment_id, 817 uint64_t max_fragment_id,
782 GNUNET_MULTICAST_JoinCallback join_cb, 818 GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
783 GNUNET_MULTICAST_MembershipTestCallback member_test_cb, 819 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
784 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 820 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
785 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 821 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
@@ -801,7 +837,7 @@ GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
801 grp->cfg = cfg; 837 grp->cfg = cfg;
802 838
803 grp->cb_cls = cls; 839 grp->cb_cls = cls;
804 grp->join_cb = join_cb; 840 grp->join_req_cb = join_request_cb;
805 grp->member_test_cb = member_test_cb; 841 grp->member_test_cb = member_test_cb;
806 grp->replay_frag_cb = replay_frag_cb; 842 grp->replay_frag_cb = replay_frag_cb;
807 grp->replay_msg_cb = replay_msg_cb; 843 grp->replay_msg_cb = replay_msg_cb;
@@ -963,7 +999,8 @@ GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginTransmitHan
963 * If empty, the @a join_request is sent directly to the @a origin. 999 * If empty, the @a join_request is sent directly to the @a origin.
964 * @param join_msg Application-dependent join message to be passed to the peer 1000 * @param join_msg Application-dependent join message to be passed to the peer
965 * @a origin. 1001 * @a origin.
966 * @param join_cb Function called to approve / disapprove joining of a peer. 1002 * @param join_request_cb Function called to approve / disapprove joining of a peer.
1003 * @param join_decision_cb Function called to inform about the join decision.
967 * @param member_test_cb Function multicast can use to test group membership. 1004 * @param member_test_cb Function multicast can use to test group membership.
968 * @param replay_frag_cb Function that can be called to replay message fragments 1005 * @param replay_frag_cb Function that can be called to replay message fragments
969 * this peer already knows from this group. NULL if this 1006 * this peer already knows from this group. NULL if this
@@ -982,10 +1019,11 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
982 const struct GNUNET_CRYPTO_EddsaPublicKey *group_key, 1019 const struct GNUNET_CRYPTO_EddsaPublicKey *group_key,
983 const struct GNUNET_CRYPTO_EddsaPrivateKey *member_key, 1020 const struct GNUNET_CRYPTO_EddsaPrivateKey *member_key,
984 const struct GNUNET_PeerIdentity *origin, 1021 const struct GNUNET_PeerIdentity *origin,
985 uint32_t relay_count, 1022 uint16_t relay_count,
986 const struct GNUNET_PeerIdentity *relays, 1023 const struct GNUNET_PeerIdentity *relays,
987 const struct GNUNET_MessageHeader *join_msg, 1024 const struct GNUNET_MessageHeader *join_msg,
988 GNUNET_MULTICAST_JoinCallback join_cb, 1025 GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
1026 GNUNET_MULTICAST_JoinDecisionCallback join_decision_cb,
989 GNUNET_MULTICAST_MembershipTestCallback member_test_cb, 1027 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
990 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 1028 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
991 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb, 1029 GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
@@ -1014,18 +1052,14 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
1014 grp->cfg = cfg; 1052 grp->cfg = cfg;
1015 grp->pub_key = *group_key; 1053 grp->pub_key = *group_key;
1016 1054
1017 grp->join_cb = join_cb; 1055 mem->join_dcsn_cb = join_decision_cb;
1056 grp->join_req_cb = join_request_cb;
1018 grp->member_test_cb = member_test_cb; 1057 grp->member_test_cb = member_test_cb;
1019 grp->replay_frag_cb = replay_frag_cb; 1058 grp->replay_frag_cb = replay_frag_cb;
1020 grp->message_cb = message_cb; 1059 grp->message_cb = message_cb;
1021 grp->cb_cls = cls; 1060 grp->cb_cls = cls;
1022 1061
1023 mem->origin = *origin; 1062 GNUNET_CRYPTO_eddsa_key_get_public (member_key, &grp->pub_key);
1024 mem->relay_count = relay_count;
1025 mem->relays = *relays;
1026 mem->priv_key = *member_key;
1027
1028 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &grp->pub_key);
1029 GNUNET_CRYPTO_hash (&grp->pub_key, sizeof (grp->pub_key), &grp->pub_key_hash); 1063 GNUNET_CRYPTO_hash (&grp->pub_key, sizeof (grp->pub_key), &grp->pub_key_hash);
1030 1064
1031 if (NULL == members) 1065 if (NULL == members)