aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2014-05-22 23:05:27 +0000
committerGabor X Toth <*@tg-x.net>2014-05-22 23:05:27 +0000
commita7100389deab562e67d22ff68961b68a62341aec (patch)
treedbafc72c162df8627e639bd5e5190d8dc321d63d /src
parentc3bc1d8ef6e78e543d0077a57b04ae480f1d7caf (diff)
downloadgnunet-a7100389deab562e67d22ff68961b68a62341aec.tar.gz
gnunet-a7100389deab562e67d22ff68961b68a62341aec.zip
psyc, multicast: join decision
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_multicast_service.h26
-rw-r--r--src/include/gnunet_protocols.h10
-rw-r--r--src/include/gnunet_psyc_service.h13
-rw-r--r--src/multicast/Makefile.am8
-rw-r--r--src/multicast/gnunet-service-multicast.c126
-rw-r--r--src/multicast/multicast.h49
-rw-r--r--src/multicast/multicast_api.c77
-rw-r--r--src/multicast/test_multicast.c (renamed from src/multicast/test_multicast_api.c)6
-rw-r--r--src/psyc/gnunet-service-psyc.c171
-rw-r--r--src/psyc/psyc.h25
-rw-r--r--src/psyc/psyc_api.c45
-rw-r--r--src/psyc/psyc_common.c2
-rw-r--r--src/psyc/test_psyc.c23
13 files changed, 445 insertions, 136 deletions
diff --git a/src/include/gnunet_multicast_service.h b/src/include/gnunet_multicast_service.h
index f1b8bc7e5..7ceb2e352 100644
--- a/src/include/gnunet_multicast_service.h
+++ b/src/include/gnunet_multicast_service.h
@@ -253,7 +253,7 @@ struct GNUNET_MULTICAST_JoinHandle;
253 * be the multicast origin) is a good candidate for building the 253 * be the multicast origin) is a good candidate for building the
254 * multicast tree. Note that it is unnecessary to specify our own 254 * multicast tree. Note that it is unnecessary to specify our own
255 * peer identity in this array. 255 * peer identity in this array.
256 * @param join_response Message to send in response to the joining peer; 256 * @param join_resp Message to send in response to the joining peer;
257 * can also be used to redirect the peer to a different group at the 257 * can also be used to redirect the peer to a different group at the
258 * application layer; this response is to be transmitted to the 258 * application layer; this response is to be transmitted to the
259 * peer that issued the request even if admission is denied. 259 * peer that issued the request even if admission is denied.
@@ -263,7 +263,7 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
263 int is_admitted, 263 int is_admitted,
264 unsigned int relay_count, 264 unsigned int relay_count,
265 const struct GNUNET_PeerIdentity *relays, 265 const struct GNUNET_PeerIdentity *relays,
266 const struct GNUNET_MessageHeader *join_response); 266 const struct GNUNET_MessageHeader *join_resp);
267 267
268 268
269/** 269/**
@@ -272,18 +272,16 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
272 * Implementations of this function must call GNUNET_MULTICAST_join_decision() 272 * Implementations of this function must call GNUNET_MULTICAST_join_decision()
273 * with the decision. 273 * with the decision.
274 * 274 *
275 * @param cls Closure. 275 * @param cls Closure.
276 * @param peer Identity of the member that wants to join. 276 * @param peer Identity of the member that wants to join.
277 * @param join_req Application-dependent join message from the new member 277 * @param member_key Requesting member's public key.
278 * (might, for example, contain a user, 278 * @param join_msg Application-dependent join message from the new member.
279 * bind user identity/pseudonym to peer identity, application-level 279 * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison().
280 * message to origin, etc.).
281 * @param jh Join handle to pass to GNUNET_MULTICAST_join_decison().
282 */ 280 */
283typedef void 281typedef void
284(*GNUNET_MULTICAST_JoinCallback) (void *cls, 282(*GNUNET_MULTICAST_JoinCallback) (void *cls,
285 const struct GNUNET_CRYPTO_EddsaPublicKey *member_key, 283 const struct GNUNET_CRYPTO_EddsaPublicKey *member_key,
286 const struct GNUNET_MessageHeader *join_req, 284 const struct GNUNET_MessageHeader *join_msg,
287 struct GNUNET_MULTICAST_JoinHandle *jh); 285 struct GNUNET_MULTICAST_JoinHandle *jh);
288 286
289 287
@@ -652,7 +650,7 @@ GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
652 * Join a multicast group. 650 * Join a multicast group.
653 * 651 *
654 * The entity joining is always the local peer. Further information about the 652 * The entity joining is always the local peer. Further information about the
655 * candidate can be provided in the @a join_request message. If the join fails, the 653 * candidate can be provided in @a join_msg. If the join fails, the
656 * @a message_cb is invoked with a (failure) response and then with NULL. If 654 * @a message_cb is invoked with a (failure) response and then with NULL. If
657 * the join succeeds, outstanding (state) messages and ongoing multicast 655 * the join succeeds, outstanding (state) messages and ongoing multicast
658 * messages will be given to the @a message_cb until the member decides to part 656 * messages will be given to the @a message_cb until the member decides to part
@@ -671,10 +669,8 @@ GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin);
671 * @param relays Peer identities of members of the group, which serve as relays 669 * @param relays Peer identities of members of the group, which serve as relays
672 * and can be used to join the group at. and send the @a join_request to. 670 * and can be used to join the group at. and send the @a join_request to.
673 * If empty, the @a join_request is sent directly to the @a origin. 671 * If empty, the @a join_request is sent directly to the @a origin.
674 * @param join_request Application-dependent join request to be passed to the peer 672 * @param join_msg Application-dependent join message to be passed to the
675 * @a relay (might, for example, contain a user, bind user 673 * @a origin.
676 * identity/pseudonym to peer identity, application-level message to
677 * origin, etc.).
678 * @param join_cb Function called to approve / disapprove joining of a peer. 674 * @param join_cb Function called to approve / disapprove joining of a peer.
679 * @param mem_test_cb Function multicast can use to test group membership. 675 * @param mem_test_cb Function multicast can use to test group membership.
680 * @param replay_frag_cb Function that can be called to replay message fragments 676 * @param replay_frag_cb Function that can be called to replay message fragments
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 11b4403f7..fba99ff43 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2398,6 +2398,16 @@ extern "C"
2398 */ 2398 */
2399#define GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST_CANCEL 760 2399#define GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST_CANCEL 760
2400 2400
2401/**
2402 * S->C: Membership test request.
2403 */
2404#define GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST 761
2405
2406/**
2407 * C->S: Membership test result.
2408 */
2409#define GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT 762
2410
2401 2411
2402 2412
2403/******************************************************************************* 2413/*******************************************************************************
diff --git a/src/include/gnunet_psyc_service.h b/src/include/gnunet_psyc_service.h
index 48c1107dc..2ae20adc5 100644
--- a/src/include/gnunet_psyc_service.h
+++ b/src/include/gnunet_psyc_service.h
@@ -327,23 +327,14 @@ typedef void
327 * 327 *
328 * @param cls Closure. 328 * @param cls Closure.
329 * @param slave requesting to join. 329 * @param slave requesting to join.
330 * @param method_name Method name in the join request. 330 * @param join_msg Join message sent along with the request.
331 * @param variable_count Number of elements in the @a variables array.
332 * @param variables Transient variables for the join request.
333 * @param data Data stream given to the method (might not be zero-terminated
334 * if data is binary).
335 * @param data_size Number of bytes in @a data.
336 * @param jh Join handle to use with GNUNET_PSYC_join_decision() 331 * @param jh Join handle to use with GNUNET_PSYC_join_decision()
337 */ 332 */
338typedef void 333typedef void
339(*GNUNET_PSYC_JoinCallback) (void *cls, 334(*GNUNET_PSYC_JoinCallback) (void *cls,
340 const struct GNUNET_CRYPTO_EddsaPublicKey 335 const struct GNUNET_CRYPTO_EddsaPublicKey
341 *slave_key, 336 *slave_key,
342 const char *method_name, 337 const struct GNUNET_PSYC_MessageHeader *join_msg,
343 size_t variable_count,
344 const struct GNUNET_ENV_Modifier *variables,
345 const void *data,
346 size_t data_size,
347 struct GNUNET_PSYC_JoinHandle *jh); 338 struct GNUNET_PSYC_JoinHandle *jh);
348 339
349 340
diff --git a/src/multicast/Makefile.am b/src/multicast/Makefile.am
index 752736c49..b2c1702e4 100644
--- a/src/multicast/Makefile.am
+++ b/src/multicast/Makefile.am
@@ -54,15 +54,15 @@ gnunet_service_multicast_DEPENDENCIES = \
54 54
55 55
56check_PROGRAMS = \ 56check_PROGRAMS = \
57 test_multicast_api 57 test_multicast
58 58
59if ENABLE_TEST_RUN 59if ENABLE_TEST_RUN
60AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; 60AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
61TESTS = $(check_PROGRAMS) 61TESTS = $(check_PROGRAMS)
62endif 62endif
63 63
64test_multicast_api_SOURCES = \ 64test_multicast_SOURCES = \
65 test_multicast_api.c 65 test_multicast.c
66test_multicast_api_LDADD = \ 66test_multicast_LDADD = \
67 $(top_builddir)/src/util/libgnunetutil.la 67 $(top_builddir)/src/util/libgnunetutil.la
68 68
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index 0394ee19e..bd6616589 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -147,7 +147,7 @@ struct Member
147 /** 147 /**
148 * Join request sent to the origin / members. 148 * Join request sent to the origin / members.
149 */ 149 */
150 struct GNUNET_MULTICAST_JoinRequest *join_request; 150 struct MulticastJoinRequestMessage *join_request;
151 151
152 /** 152 /**
153 * Join decision sent in reply to our request. 153 * Join decision sent in reply to our request.
@@ -206,6 +206,8 @@ cleanup_member (struct Member *mem)
206 grp_mem); 206 grp_mem);
207 GNUNET_CONTAINER_multihashmap_destroy (grp_mem); 207 GNUNET_CONTAINER_multihashmap_destroy (grp_mem);
208 } 208 }
209 if (NULL != mem->join_decision)
210 GNUNET_free (mem->join_decision);
209 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem); 211 GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem);
210} 212}
211 213
@@ -425,8 +427,8 @@ static void
425handle_member_join (void *cls, struct GNUNET_SERVER_Client *client, 427handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
426 const struct GNUNET_MessageHeader *m) 428 const struct GNUNET_MessageHeader *m)
427{ 429{
428 struct MulticastMemberJoinMessage * 430 const struct MulticastMemberJoinMessage *
429 msg = (struct MulticastMemberJoinMessage *) m; 431 msg = (const struct MulticastMemberJoinMessage *) m;
430 432
431 struct GNUNET_CRYPTO_EddsaPublicKey mem_pub_key; 433 struct GNUNET_CRYPTO_EddsaPublicKey mem_pub_key;
432 struct GNUNET_HashCode pub_key_hash, mem_pub_key_hash; 434 struct GNUNET_HashCode pub_key_hash, mem_pub_key_hash;
@@ -440,17 +442,10 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
440 struct Member *mem = NULL; 442 struct Member *mem = NULL;
441 struct Group *grp; 443 struct Group *grp;
442 444
443 if (NULL == grp_mem) 445 if (NULL != grp_mem)
444 {
445 grp_mem = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
446 GNUNET_CONTAINER_multihashmap_put (group_members, &pub_key_hash, grp_mem,
447 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
448 }
449 else
450 { 446 {
451 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &mem_pub_key_hash); 447 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &mem_pub_key_hash);
452 } 448 }
453
454 if (NULL == mem) 449 if (NULL == mem)
455 { 450 {
456 mem = GNUNET_new (struct Member); 451 mem = GNUNET_new (struct Member);
@@ -463,7 +458,13 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
463 grp->pub_key = msg->group_key; 458 grp->pub_key = msg->group_key;
464 grp->pub_key_hash = pub_key_hash; 459 grp->pub_key_hash = pub_key_hash;
465 460
466 GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem_pub_key_hash, mem, 461 if (NULL == grp_mem)
462 {
463 grp_mem = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
464 GNUNET_CONTAINER_multihashmap_put (group_members, &grp->pub_key_hash, grp_mem,
465 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
466 }
467 GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem->pub_key_hash, mem,
467 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 468 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
468 GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem, 469 GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem,
469 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 470 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -478,8 +479,11 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
478 GNUNET_CONTAINER_DLL_insert (grp->clients_head, grp->clients_tail, cl); 479 GNUNET_CONTAINER_DLL_insert (grp->clients_head, grp->clients_tail, cl);
479 480
480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 481 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
481 "%p Client connected as member to group %s.\n", 482 "%p Client connected to group %s..\n",
482 mem, GNUNET_h2s (&grp->pub_key_hash)); 483 mem, GNUNET_h2s (&grp->pub_key_hash));
484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
485 "%p ..as member %s.\n",
486 mem, GNUNET_h2s (&mem_pub_key_hash));
483 487
484 GNUNET_SERVER_client_set_user_context (client, grp); 488 GNUNET_SERVER_client_set_user_context (client, grp);
485 489
@@ -496,19 +500,19 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
496 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1]; 500 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &msg[1];
497 uint32_t relay_count = ntohs (msg->relay_count); 501 uint32_t relay_count = ntohs (msg->relay_count);
498 struct GNUNET_MessageHeader * 502 struct GNUNET_MessageHeader *
499 join_req = ((struct GNUNET_MessageHeader *) 503 join_msg = ((struct GNUNET_MessageHeader *)
500 ((char *) &msg[1]) + relay_count * sizeof (*relays)); 504 ((char *) &msg[1]) + relay_count * sizeof (*relays));
501 uint16_t join_req_size = ntohs (join_req->size); 505 uint16_t join_msg_size = ntohs (join_msg->size);
502 506
503 struct MulticastJoinRequestMessage * 507 struct MulticastJoinRequestMessage *
504 req = GNUNET_malloc (sizeof (*req) + join_req_size); 508 req = GNUNET_malloc (sizeof (*req) + join_msg_size);
505 req->header.size = htons (sizeof (*req) + join_req_size); 509 req->header.size = htons (sizeof (*req) + join_msg_size);
506 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST); 510 req->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST);
507 req->group_key = grp->pub_key; 511 req->group_key = grp->pub_key;
508 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key); 512 GNUNET_CRYPTO_eddsa_key_get_public (&mem->priv_key, &req->member_key);
509 memcpy (&req[1], join_req, join_req_size); 513 memcpy (&req[1], join_msg, join_msg_size);
510 514
511 req->purpose.size = htonl (sizeof (*req) + join_req_size 515 req->purpose.size = htonl (sizeof (*req) + join_msg_size
512 - sizeof (req->header) 516 - sizeof (req->header)
513 - sizeof (req->signature)); 517 - sizeof (req->signature));
514 req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST); 518 req->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST);
@@ -531,7 +535,7 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
531 } 535 }
532 else 536 else
533 { 537 {
534 /* FIXME: send join request to remote origin / members */ 538 /* FIXME: send join request to remote peers */
535 } 539 }
536 } 540 }
537 GNUNET_SERVER_receive_done (client, GNUNET_OK); 541 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -539,6 +543,85 @@ handle_member_join (void *cls, struct GNUNET_SERVER_Client *client,
539 543
540 544
541/** 545/**
546 * Join decision from client.
547 */
548static void
549handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
550 const struct GNUNET_MessageHeader *m)
551{
552 struct Group *
553 grp = GNUNET_SERVER_client_get_user_context (client, struct Group);
554 const struct MulticastClientJoinDecisionMessage *
555 cl_dcsn = (const struct MulticastClientJoinDecisionMessage *) m;
556
557 struct GNUNET_PeerIdentity *relays = (struct GNUNET_PeerIdentity *) &cl_dcsn[1];
558 uint32_t relay_count = ntohs (cl_dcsn->relay_count);
559
560 struct GNUNET_MessageHeader *join_msg = NULL;
561 uint16_t join_msg_size = 0;
562 if (sizeof (*cl_dcsn) + relay_count * sizeof (*relays) + sizeof (*m)
563 <= ntohs (m->size))
564 {
565 join_msg = ((struct GNUNET_MessageHeader *)
566 ((char *) &cl_dcsn[1]) + relay_count * sizeof (*relays));
567 join_msg_size = ntohs (join_msg->size);
568 }
569
570 struct MulticastJoinDecisionMessage *
571 dcsn = GNUNET_malloc (sizeof (*dcsn) + join_msg_size);
572 dcsn->header.size = htons (sizeof (*dcsn) + join_msg_size);
573 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
574 dcsn->is_admitted = cl_dcsn->is_admitted;
575 memcpy (&dcsn[1], join_msg, join_msg_size);
576
577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
578 "%p Got join decision from client for group %s..\n",
579 grp, GNUNET_h2s (&grp->pub_key_hash));
580
581 if (GNUNET_YES
582 == GNUNET_CONTAINER_multihashmap_contains (origins, &grp->pub_key_hash))
583 { /* Local origin */
584 struct GNUNET_CONTAINER_MultiHashMap *
585 grp_mem = GNUNET_CONTAINER_multihashmap_get (group_members,
586 &grp->pub_key_hash);
587 if (NULL != grp_mem)
588 {
589 struct GNUNET_HashCode member_key_hash;
590 GNUNET_CRYPTO_hash (&cl_dcsn->member_key, sizeof (cl_dcsn->member_key),
591 &member_key_hash);
592 struct Member *
593 mem = GNUNET_CONTAINER_multihashmap_get (grp_mem, &member_key_hash);
594 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
595 "%p ..and member %s: %p\n",
596 grp, GNUNET_h2s (&member_key_hash), mem);
597 if (NULL != mem)
598 {
599 message_to_clients (grp, (struct GNUNET_MessageHeader *) dcsn);
600 if (GNUNET_YES == dcsn->is_admitted)
601 { /* Member admitted, store join_decision. */
602 mem->join_decision = dcsn;
603 }
604 else
605 { /* Refused entry, disconnect clients. */
606 GNUNET_free (dcsn);
607 struct ClientList *cl = mem->grp.clients_head;
608 while (NULL != cl)
609 {
610 GNUNET_SERVER_client_disconnect (cl->client);
611 cl = cl->next;
612 }
613 }
614 }
615 }
616 }
617 else
618 {
619 /* FIXME: send join decision to remote peers */
620 }
621 GNUNET_SERVER_receive_done (client, GNUNET_OK);
622}
623
624/**
542 * Incoming message from a client. 625 * Incoming message from a client.
543 */ 626 */
544static void 627static void
@@ -633,6 +716,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
633 { &handle_member_join, NULL, 716 { &handle_member_join, NULL,
634 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 }, 717 GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN, 0 },
635 718
719 { &handle_join_decision, NULL,
720 GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 },
721
636 { &handle_multicast_message, NULL, 722 { &handle_multicast_message, NULL,
637 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, 723 GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 },
638 724
diff --git a/src/multicast/multicast.h b/src/multicast/multicast.h
index 5b0fc647c..85c5714e6 100644
--- a/src/multicast/multicast.h
+++ b/src/multicast/multicast.h
@@ -36,11 +36,16 @@ GNUNET_NETWORK_STRUCT_BEGIN
36struct MulticastJoinRequestMessage 36struct MulticastJoinRequestMessage
37{ 37{
38 /** 38 /**
39 * Header for the join request. 39 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST
40 */ 40 */
41 struct GNUNET_MessageHeader header; 41 struct GNUNET_MessageHeader header;
42 42
43 /** 43 /**
44 * Always zero.
45 */
46 uint32_t reserved;
47
48 /**
44 * ECC signature of the rest of the fields of the join request. 49 * ECC signature of the rest of the fields of the join request.
45 * 50 *
46 * Signature must match the public key of the joining member. 51 * Signature must match the public key of the joining member.
@@ -72,31 +77,55 @@ struct MulticastJoinRequestMessage
72 77
73 78
74/** 79/**
75 * Message sent from the client to the service to notify the service 80 * Header of a join decision sent to a remote peer.
76 * about a join decision.
77 */ 81 */
78struct MulticastJoinDecisionMessage 82struct MulticastJoinDecisionMessage
79{ 83{
80 /** 84 /**
81 * 85 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION
82 */ 86 */
83 struct GNUNET_MessageHeader header; 87 struct GNUNET_MessageHeader header;
84 88
85 /** 89 /**
86 * Unique ID that identifies the associated join test. 90 * #GNUNET_YES if the peer was admitted.
87 */ 91 */
88 uint32_t uid; 92 uint8_t is_admitted;
89 93
94 /* Followed by the join response message */
95};
96
97
98/**
99 * Message sent from the client to the service to notify the service
100 * about a join decision.
101 */
102struct MulticastClientJoinDecisionMessage
103{
90 /** 104 /**
91 * #GNUNET_YES if the peer was admitted. 105 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION
92 */ 106 */
93 int32_t is_admitted; 107 struct GNUNET_MessageHeader header;
94 108
95 /** 109 /**
96 * Number of relays given. 110 * Number of relays given.
97 */ 111 */
98 uint32_t relay_count; 112 uint32_t relay_count;
99 113
114 /**
115 * Public key of the joining member.
116 */
117 struct GNUNET_CRYPTO_EddsaPublicKey member_key;
118
119 /**
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
100 /* Followed by relay_count peer identities */ 129 /* Followed by relay_count peer identities */
101 130
102 /* Followed by the join response message */ 131 /* Followed by the join response message */
@@ -108,11 +137,11 @@ struct MulticastJoinDecisionMessage
108 * Message sent from the client to the service to notify the service 137 * Message sent from the client to the service to notify the service
109 * about the result of a membership test. 138 * about the result of a membership test.
110 */ 139 */
111struct MulticastMembershipTestResponseMessage 140struct MulticastMembershipTestResultMessage
112{ 141{
113 142
114 /** 143 /**
115 * 144 * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT
116 */ 145 */
117 struct GNUNET_MessageHeader header; 146 struct GNUNET_MessageHeader header;
118 147
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index 84dac0545..477cb1f2c 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -182,8 +182,6 @@ struct GNUNET_MULTICAST_Member
182 struct GNUNET_PeerIdentity relays; 182 struct GNUNET_PeerIdentity relays;
183 uint32_t relay_count; 183 uint32_t relay_count;
184 184
185 struct GNUNET_MessageHeader *join_request;
186
187 uint64_t next_fragment_id; 185 uint64_t next_fragment_id;
188}; 186};
189 187
@@ -501,7 +499,7 @@ join_request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
501 499
502 const struct GNUNET_MessageHeader *msg = NULL; 500 const struct GNUNET_MessageHeader *msg = NULL;
503 if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size)) 501 if (sizeof (*req) + sizeof (*msg) <= ntohs (req->header.size))
504 msg =(const struct GNUNET_MessageHeader *) &req[1]; 502 msg = (const struct GNUNET_MessageHeader *) &req[1];
505 503
506 grp->join_cb (grp->cb_cls, &req->member_key, msg, jh); 504 grp->join_cb (grp->cb_cls, &req->member_key, msg, jh);
507 return GNUNET_YES; 505 return GNUNET_YES;
@@ -509,6 +507,25 @@ join_request_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
509 507
510 508
511/** 509/**
510 * Iterator callback for calling join decision callbacks of members.
511 */
512static int
513join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
514 void *member)
515{
516 const struct MulticastJoinDecisionMessage *dcsn = cls;
517 struct GNUNET_MULTICAST_Member *mem = member;
518 struct GNUNET_MULTICAST_Group *grp = &mem->grp;
519
520 const struct GNUNET_MessageHeader *msg = NULL;
521 if (sizeof (*dcsn) + sizeof (*msg) <= ntohs (dcsn->header.size))
522 msg = (const struct GNUNET_MessageHeader *) &dcsn[1];
523
524 // FIXME: grp->join_decision_cb (grp->cb_cls, msg);
525 return GNUNET_YES;
526}
527
528/**
512 * Function called when we receive a message from the service. 529 * Function called when we receive a message from the service.
513 * 530 *
514 * @param cls struct GNUNET_MULTICAST_Group 531 * @param cls struct GNUNET_MULTICAST_Group
@@ -549,6 +566,10 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
549 size_min = sizeof (struct MulticastJoinRequestMessage); 566 size_min = sizeof (struct MulticastJoinRequestMessage);
550 break; 567 break;
551 568
569 case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION:
570 size_min = sizeof (struct MulticastJoinDecisionMessage);
571 break;
572
552 default: 573 default:
553 GNUNET_break_op (0); 574 GNUNET_break_op (0);
554 type = 0; 575 type = 0;
@@ -592,6 +613,15 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
592 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash, 613 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash,
593 join_request_cb, (void *) msg); 614 join_request_cb, (void *) msg);
594 break; 615 break;
616
617 case GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION:
618 if (NULL != origins)
619 GNUNET_CONTAINER_multihashmap_get_multiple (origins, &grp->pub_key_hash,
620 join_decision_cb, (void *) msg);
621 if (NULL != members)
622 GNUNET_CONTAINER_multihashmap_get_multiple (members, &grp->pub_key_hash,
623 join_decision_cb, (void *) msg);
624 break;
595 } 625 }
596 626
597 if (NULL != grp->client) 627 if (NULL != grp->client)
@@ -619,7 +649,7 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
619 * be the multicast origin) is a good candidate for building the 649 * be the multicast origin) is a good candidate for building the
620 * multicast tree. Note that it is unnecessary to specify our own 650 * multicast tree. Note that it is unnecessary to specify our own
621 * peer identity in this array. 651 * peer identity in this array.
622 * @param join_response Message to send in response to the joining peer; 652 * @param join_resp Message to send in response to the joining peer;
623 * can also be used to redirect the peer to a different group at the 653 * can also be used to redirect the peer to a different group at the
624 * application layer; this response is to be transmitted to the 654 * application layer; this response is to be transmitted to the
625 * peer that issued the request even if admission is denied. 655 * peer that issued the request even if admission is denied.
@@ -629,8 +659,29 @@ GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
629 int is_admitted, 659 int is_admitted,
630 unsigned int relay_count, 660 unsigned int relay_count,
631 const struct GNUNET_PeerIdentity *relays, 661 const struct GNUNET_PeerIdentity *relays,
632 const struct GNUNET_MessageHeader *join_response) 662 const struct GNUNET_MessageHeader *join_resp)
633{ 663{
664 struct GNUNET_MULTICAST_Group *grp = jh->group;
665 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0;
666 uint16_t relay_size = relay_count * sizeof (*relays);
667 struct MulticastClientJoinDecisionMessage * dcsn;
668 struct MessageQueue *
669 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn)
670 + relay_size + join_resp_size);
671
672 dcsn = (struct MulticastClientJoinDecisionMessage *) &mq[1];
673 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION);
674 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size);
675 dcsn->member_key = jh->member_key;
676 dcsn->member_peer = jh->member_peer;
677 dcsn->is_admitted = is_admitted;
678 dcsn->relay_count = relay_count;
679 memcpy (&dcsn[1], relays, relay_size);
680 memcpy (((char *) &dcsn[1]) + relay_size, join_resp, join_resp_size);
681
682 GNUNET_CONTAINER_DLL_insert_tail (grp->tmit_head, grp->tmit_tail, mq);
683 transmit_next (grp);
684
634 GNUNET_free (jh); 685 GNUNET_free (jh);
635 return NULL; 686 return NULL;
636} 687}
@@ -908,10 +959,8 @@ GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginTransmitHan
908 * @param relays Peer identities of members of the group, which serve as relays 959 * @param relays Peer identities of members of the group, which serve as relays
909 * and can be used to join the group at. and send the @a join_request to. 960 * and can be used to join the group at. and send the @a join_request to.
910 * If empty, the @a join_request is sent directly to the @a origin. 961 * If empty, the @a join_request is sent directly to the @a origin.
911 * @param join_req Application-dependent join request to be passed to the peer 962 * @param join_msg Application-dependent join message to be passed to the peer
912 * @a relay (might, for example, contain a user, bind user 963 * @a origin.
913 * identity/pseudonym to peer identity, application-level message to
914 * origin, etc.).
915 * @param join_cb Function called to approve / disapprove joining of a peer. 964 * @param join_cb Function called to approve / disapprove joining of a peer.
916 * @param member_test_cb Function multicast can use to test group membership. 965 * @param member_test_cb Function multicast can use to test group membership.
917 * @param replay_frag_cb Function that can be called to replay message fragments 966 * @param replay_frag_cb Function that can be called to replay message fragments
@@ -933,7 +982,7 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
933 const struct GNUNET_PeerIdentity *origin, 982 const struct GNUNET_PeerIdentity *origin,
934 uint32_t relay_count, 983 uint32_t relay_count,
935 const struct GNUNET_PeerIdentity *relays, 984 const struct GNUNET_PeerIdentity *relays,
936 const struct GNUNET_MessageHeader *join_req, 985 const struct GNUNET_MessageHeader *join_msg,
937 GNUNET_MULTICAST_JoinCallback join_cb, 986 GNUNET_MULTICAST_JoinCallback join_cb,
938 GNUNET_MULTICAST_MembershipTestCallback member_test_cb, 987 GNUNET_MULTICAST_MembershipTestCallback member_test_cb,
939 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb, 988 GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
@@ -945,16 +994,16 @@ GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
945 struct GNUNET_MULTICAST_Group *grp = &mem->grp; 994 struct GNUNET_MULTICAST_Group *grp = &mem->grp;
946 995
947 uint16_t relay_size = relay_count * sizeof (*relays); 996 uint16_t relay_size = relay_count * sizeof (*relays);
948 uint16_t join_req_size = (NULL != join_req) ? ntohs (join_req->size) : 0; 997 uint16_t join_msg_size = (NULL != join_msg) ? ntohs (join_msg->size) : 0;
949 struct MulticastMemberJoinMessage * 998 struct MulticastMemberJoinMessage *
950 join = GNUNET_malloc (sizeof (*join) + relay_size + join_req_size); 999 join = GNUNET_malloc (sizeof (*join) + relay_size + join_msg_size);
951 join->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN); 1000 join->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN);
952 join->header.size = htons (sizeof (*join) + relay_size + join_req_size); 1001 join->header.size = htons (sizeof (*join) + relay_size + join_msg_size);
953 join->group_key = *group_key; 1002 join->group_key = *group_key;
954 join->member_key = *member_key; 1003 join->member_key = *member_key;
955 join->origin = *origin; 1004 join->origin = *origin;
956 memcpy (&join[1], relays, relay_size); 1005 memcpy (&join[1], relays, relay_size);
957 memcpy (((char *) &join[1]) + relay_size, join_req, join_req_size); 1006 memcpy (((char *) &join[1]) + relay_size, join_msg, join_msg_size);
958 1007
959 grp->reconnect_msg = (struct GNUNET_MessageHeader *) join; 1008 grp->reconnect_msg = (struct GNUNET_MessageHeader *) join;
960 grp->is_origin = GNUNET_NO; 1009 grp->is_origin = GNUNET_NO;
diff --git a/src/multicast/test_multicast_api.c b/src/multicast/test_multicast.c
index 25224f043..244634c64 100644
--- a/src/multicast/test_multicast_api.c
+++ b/src/multicast/test_multicast.c
@@ -18,8 +18,8 @@
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20/** 20/**
21 * @file multicast/test_multicast_api.c 21 * @file multicast/test_multicast.c
22 * @brief testcase for multicast.c 22 * @brief testcase for multicast_api.c
23 */ 23 */
24#include "platform.h" 24#include "platform.h"
25#include "gnunet_util_lib.h" 25#include "gnunet_util_lib.h"
@@ -41,4 +41,4 @@ main (int argc, char *argv[])
41 return ret; 41 return ret;
42} 42}
43 43
44/* end of test_multicast_api.c */ 44/* end of test_multicast.c */
diff --git a/src/psyc/gnunet-service-psyc.c b/src/psyc/gnunet-service-psyc.c
index 765371d77..7669eed15 100644
--- a/src/psyc/gnunet-service-psyc.c
+++ b/src/psyc/gnunet-service-psyc.c
@@ -194,6 +194,11 @@ struct Channel
194 struct TransmitMessage *tmit_tail; 194 struct TransmitMessage *tmit_tail;
195 195
196 /** 196 /**
197 * Current PSYCstore operation.
198 */
199 struct GNUNET_PSYCSTORE_OperationHandle *store_op;
200
201 /**
197 * Received fragments not yet sent to the client. 202 * Received fragments not yet sent to the client.
198 * message_id -> FragmentQueue 203 * message_id -> FragmentQueue
199 */ 204 */
@@ -277,7 +282,7 @@ struct Master
277 /** 282 /**
278 * Channel struct common for Master and Slave 283 * Channel struct common for Master and Slave
279 */ 284 */
280 struct Channel channel; 285 struct Channel ch;
281 286
282 /** 287 /**
283 * Private key of the channel. 288 * Private key of the channel.
@@ -295,6 +300,12 @@ struct Master
295 struct GNUNET_MULTICAST_OriginTransmitHandle *tmit_handle; 300 struct GNUNET_MULTICAST_OriginTransmitHandle *tmit_handle;
296 301
297 /** 302 /**
303 * Incoming join requests from multicast.
304 * member_key -> struct GNUNET_MULTICAST_JoinHandle *
305 */
306 struct GNUNET_CONTAINER_MultiHashMap *join_reqs;
307
308 /**
298 * Last message ID transmitted to this channel. 309 * Last message ID transmitted to this channel.
299 * 310 *
300 * Incremented before sending a message, thus the message_id in messages sent 311 * Incremented before sending a message, thus the message_id in messages sent
@@ -328,7 +339,7 @@ struct Slave
328 /** 339 /**
329 * Channel struct common for Master and Slave 340 * Channel struct common for Master and Slave
330 */ 341 */
331 struct Channel channel; 342 struct Channel ch;
332 343
333 /** 344 /**
334 * Private key of the slave. 345 * Private key of the slave.
@@ -414,10 +425,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
414static void 425static void
415cleanup_master (struct Master *mst) 426cleanup_master (struct Master *mst)
416{ 427{
417 struct Channel *ch = &mst->channel; 428 struct Channel *ch = &mst->ch;
418 429
419 if (NULL != mst->origin) 430 if (NULL != mst->origin)
420 GNUNET_MULTICAST_origin_stop (mst->origin); 431 GNUNET_MULTICAST_origin_stop (mst->origin);
432 GNUNET_CONTAINER_multihashmap_destroy (mst->join_reqs);
421 GNUNET_CONTAINER_multihashmap_remove (masters, &ch->pub_key_hash, ch); 433 GNUNET_CONTAINER_multihashmap_remove (masters, &ch->pub_key_hash, ch);
422} 434}
423 435
@@ -428,7 +440,7 @@ cleanup_master (struct Master *mst)
428static void 440static void
429cleanup_slave (struct Slave *slv) 441cleanup_slave (struct Slave *slv)
430{ 442{
431 struct Channel *ch = &slv->channel; 443 struct Channel *ch = &slv->ch;
432 struct GNUNET_CONTAINER_MultiHashMap * 444 struct GNUNET_CONTAINER_MultiHashMap *
433 ch_slv = GNUNET_CONTAINER_multihashmap_get (channel_slaves, 445 ch_slv = GNUNET_CONTAINER_multihashmap_get (channel_slaves,
434 &ch->pub_key_hash); 446 &ch->pub_key_hash);
@@ -461,6 +473,9 @@ cleanup_channel (struct Channel *ch)
461{ 473{
462 /* FIXME: fragment_cache_clear */ 474 /* FIXME: fragment_cache_clear */
463 475
476 if (NULL != ch->store_op)
477 GNUNET_PSYCSTORE_operation_cancel (ch->store_op);
478
464 (GNUNET_YES == ch->is_master) 479 (GNUNET_YES == ch->is_master)
465 ? cleanup_master ((struct Master *) ch) 480 ? cleanup_master ((struct Master *) ch)
466 : cleanup_slave ((struct Slave *) ch); 481 : cleanup_slave ((struct Slave *) ch);
@@ -481,8 +496,8 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
481 if (NULL == client) 496 if (NULL == client)
482 return; 497 return;
483 498
484 struct Channel *ch 499 struct Channel *
485 = GNUNET_SERVER_client_get_user_context (client, struct Channel); 500 ch = GNUNET_SERVER_client_get_user_context (client, struct Channel);
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
487 "%p Client (%s) disconnected from channel %s\n", 502 "%p Client (%s) disconnected from channel %s\n",
488 ch, (GNUNET_YES == ch->is_master) ? "master" : "slave", 503 ch, (GNUNET_YES == ch->is_master) ? "master" : "slave",
@@ -545,8 +560,9 @@ msg_to_clients (const struct Channel *ch,
545/** 560/**
546 * Closure for join_mem_test_cb() 561 * Closure for join_mem_test_cb()
547 */ 562 */
548struct JoinMemTestCls 563struct JoinMemTestClosure
549{ 564{
565 struct GNUNET_CRYPTO_EddsaPublicKey slave_key;
550 struct Channel *ch; 566 struct Channel *ch;
551 struct GNUNET_MULTICAST_JoinHandle *jh; 567 struct GNUNET_MULTICAST_JoinHandle *jh;
552 struct MasterJoinRequest *master_join_req; 568 struct MasterJoinRequest *master_join_req;
@@ -559,17 +575,23 @@ struct JoinMemTestCls
559static void 575static void
560join_mem_test_cb (void *cls, int64_t result, const char *err_msg) 576join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
561{ 577{
562 struct JoinMemTestCls *jcls = cls; 578 struct JoinMemTestClosure *jcls = cls;
563 579
564 if (GNUNET_NO == result && GNUNET_YES == jcls->ch->is_master) 580 if (GNUNET_NO == result && GNUNET_YES == jcls->ch->is_master)
565 { /* Pass on join request to client if this is a master channel */ 581 { /* Pass on join request to client if this is a master channel */
582 struct Master *mst = (struct Master *) jcls->ch;
583 struct GNUNET_HashCode slave_key_hash;
584 GNUNET_CRYPTO_hash (&jcls->slave_key, sizeof (jcls->slave_key),
585 &slave_key_hash);
586 GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh,
587 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
566 msg_to_clients (jcls->ch, 588 msg_to_clients (jcls->ch,
567 (struct GNUNET_MessageHeader *) jcls->master_join_req); 589 (struct GNUNET_MessageHeader *) jcls->master_join_req);
568 } 590 }
569 else 591 else
570 { 592 {
571 // FIXME: relays 593 // FIXME: add relays
572 GNUNET_MULTICAST_join_decision(jcls->jh, result, 0, NULL, NULL); 594 GNUNET_MULTICAST_join_decision (jcls->jh, result, 0, NULL, NULL);
573 } 595 }
574 GNUNET_free (jcls->master_join_req); 596 GNUNET_free (jcls->master_join_req);
575 GNUNET_free (jcls); 597 GNUNET_free (jcls);
@@ -581,20 +603,35 @@ join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
581 */ 603 */
582static void 604static void
583join_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 605join_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
584 const struct GNUNET_MessageHeader *join_req, 606 const struct GNUNET_MessageHeader *join_msg,
585 struct GNUNET_MULTICAST_JoinHandle *jh) 607 struct GNUNET_MULTICAST_JoinHandle *jh)
586{ 608{
587 struct Channel *ch = cls; 609 struct Channel *ch = cls;
588 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join request.\n", ch); 610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join request.\n", ch);
589 611
590 uint16_t join_req_size = (NULL != join_req) ? ntohs (join_req->size) : 0; 612 uint16_t join_msg_size = 0;
591 struct MasterJoinRequest *req = GNUNET_malloc (sizeof (*req) + join_req_size); 613 if (NULL != join_msg)
592 req->header.size = htons (sizeof (*req) + join_req_size); 614 {
615 if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE == ntohs (join_msg->type))
616 {
617 join_msg_size = ntohs (join_msg->size);
618 }
619 else
620 {
621 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
622 "%p Got join message with invalid type %u.\n",
623 ch, ntohs (join_msg->type));
624 }
625 }
626
627 struct MasterJoinRequest *req = GNUNET_malloc (sizeof (*req) + join_msg_size);
628 req->header.size = htons (sizeof (*req) + join_msg_size);
593 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST); 629 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST);
594 req->slave_key = *slave_key; 630 req->slave_key = *slave_key;
595 memcpy (&req[1], join_req, join_req_size); 631 memcpy (&req[1], join_msg, join_msg_size);
596 632
597 struct JoinMemTestCls *jcls = GNUNET_malloc (sizeof (*jcls)); 633 struct JoinMemTestClosure *jcls = GNUNET_malloc (sizeof (*jcls));
634 jcls->slave_key = *slave_key;
598 jcls->ch = ch; 635 jcls->ch = ch;
599 jcls->jh = jh; 636 jcls->jh = jh;
600 jcls->master_join_req = req; 637 jcls->master_join_req = req;
@@ -1108,7 +1145,7 @@ request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
1108 enum GNUNET_MULTICAST_MessageFlags flags) 1145 enum GNUNET_MULTICAST_MessageFlags flags)
1109{ 1146{
1110 struct Master *mst = cls; 1147 struct Master *mst = cls;
1111 struct Channel *ch = &mst->channel; 1148 struct Channel *ch = &mst->ch;
1112 1149
1113 uint16_t type = ntohs (msg->type); 1150 uint16_t type = ntohs (msg->type);
1114 uint16_t size = ntohs (msg->size); 1151 uint16_t size = ntohs (msg->size);
@@ -1167,7 +1204,8 @@ master_counters_cb (void *cls, int result, uint64_t max_fragment_id,
1167 uint64_t max_state_message_id) 1204 uint64_t max_state_message_id)
1168{ 1205{
1169 struct Master *mst = cls; 1206 struct Master *mst = cls;
1170 struct Channel *ch = &mst->channel; 1207 struct Channel *ch = &mst->ch;
1208 ch->store_op = NULL;
1171 1209
1172 struct CountersResult res; 1210 struct CountersResult res;
1173 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK); 1211 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK);
@@ -1210,7 +1248,8 @@ slave_counters_cb (void *cls, int result, uint64_t max_fragment_id,
1210 uint64_t max_state_message_id) 1248 uint64_t max_state_message_id)
1211{ 1249{
1212 struct Slave *slv = cls; 1250 struct Slave *slv = cls;
1213 struct Channel *ch = &slv->channel; 1251 struct Channel *ch = &slv->ch;
1252 ch->store_op = NULL;
1214 1253
1215 struct CountersResult res; 1254 struct CountersResult res;
1216 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK); 1255 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK);
@@ -1278,8 +1317,9 @@ handle_master_start (void *cls, struct GNUNET_SERVER_Client *client,
1278 mst = GNUNET_new (struct Master); 1317 mst = GNUNET_new (struct Master);
1279 mst->policy = ntohl (req->policy); 1318 mst->policy = ntohl (req->policy);
1280 mst->priv_key = req->channel_key; 1319 mst->priv_key = req->channel_key;
1320 mst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1281 1321
1282 ch = &mst->channel; 1322 ch = &mst->ch;
1283 ch->is_master = GNUNET_YES; 1323 ch->is_master = GNUNET_YES;
1284 ch->pub_key = pub_key; 1324 ch->pub_key = pub_key;
1285 ch->pub_key_hash = pub_key_hash; 1325 ch->pub_key_hash = pub_key_hash;
@@ -1287,11 +1327,12 @@ handle_master_start (void *cls, struct GNUNET_SERVER_Client *client,
1287 1327
1288 GNUNET_CONTAINER_multihashmap_put (masters, &ch->pub_key_hash, ch, 1328 GNUNET_CONTAINER_multihashmap_put (masters, &ch->pub_key_hash, ch,
1289 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1329 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1290 GNUNET_PSYCSTORE_counters_get (store, &ch->pub_key, master_counters_cb, mst); 1330 ch->store_op = GNUNET_PSYCSTORE_counters_get (store, &ch->pub_key,
1331 master_counters_cb, mst);
1291 } 1332 }
1292 else 1333 else
1293 { 1334 {
1294 ch = &mst->channel; 1335 ch = &mst->ch;
1295 1336
1296 struct CountersResult res; 1337 struct CountersResult res;
1297 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK); 1338 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK);
@@ -1339,17 +1380,10 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1339 struct Slave *slv = NULL; 1380 struct Slave *slv = NULL;
1340 struct Channel *ch; 1381 struct Channel *ch;
1341 1382
1342 if (NULL == ch_slv) 1383 if (NULL != ch_slv)
1343 {
1344 ch_slv = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1345 GNUNET_CONTAINER_multihashmap_put (channel_slaves, &pub_key_hash, ch_slv,
1346 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1347 }
1348 else
1349 { 1384 {
1350 slv = GNUNET_CONTAINER_multihashmap_get (ch_slv, &slv_pub_key_hash); 1385 slv = GNUNET_CONTAINER_multihashmap_get (ch_slv, &slv_pub_key_hash);
1351 } 1386 }
1352
1353 if (NULL == slv) 1387 if (NULL == slv)
1354 { 1388 {
1355 slv = GNUNET_new (struct Slave); 1389 slv = GNUNET_new (struct Slave);
@@ -1367,21 +1401,28 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1367 memcpy (&slv->relays[i], &relays[i], sizeof (*relays)); 1401 memcpy (&slv->relays[i], &relays[i], sizeof (*relays));
1368 } 1402 }
1369 1403
1370 ch = &slv->channel; 1404 ch = &slv->ch;
1371 ch->is_master = GNUNET_NO; 1405 ch->is_master = GNUNET_NO;
1372 ch->pub_key = req->channel_key; 1406 ch->pub_key = req->channel_key;
1373 ch->pub_key_hash = pub_key_hash; 1407 ch->pub_key_hash = pub_key_hash;
1374 channel_init (ch); 1408 channel_init (ch);
1375 1409
1410 if (NULL == ch_slv)
1411 {
1412 ch_slv = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1413 GNUNET_CONTAINER_multihashmap_put (channel_slaves, &pub_key_hash, ch_slv,
1414 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1415 }
1376 GNUNET_CONTAINER_multihashmap_put (ch_slv, &slv_pub_key_hash, ch, 1416 GNUNET_CONTAINER_multihashmap_put (ch_slv, &slv_pub_key_hash, ch,
1377 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1417 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1378 GNUNET_CONTAINER_multihashmap_put (slaves, &ch->pub_key_hash, ch, 1418 GNUNET_CONTAINER_multihashmap_put (slaves, &ch->pub_key_hash, ch,
1379 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1419 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1380 GNUNET_PSYCSTORE_counters_get (store, &ch->pub_key, slave_counters_cb, slv); 1420 ch->store_op = GNUNET_PSYCSTORE_counters_get (store, &ch->pub_key,
1421 slave_counters_cb, slv);
1381 } 1422 }
1382 else 1423 else
1383 { 1424 {
1384 ch = &slv->channel; 1425 ch = &slv->ch;
1385 1426
1386 struct CountersResult res; 1427 struct CountersResult res;
1387 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK); 1428 res.header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK);
@@ -1402,7 +1443,58 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1402 cl->client = client; 1443 cl->client = client;
1403 GNUNET_CONTAINER_DLL_insert (ch->clients_head, ch->clients_tail, cl); 1444 GNUNET_CONTAINER_DLL_insert (ch->clients_head, ch->clients_tail, cl);
1404 1445
1405 GNUNET_SERVER_client_set_user_context (client, &slv->channel); 1446 GNUNET_SERVER_client_set_user_context (client, &slv->ch);
1447 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1448}
1449
1450
1451struct JoinDecisionClosure
1452{
1453 uint8_t is_admitted;
1454 struct GNUNET_MessageHeader *msg;
1455};
1456
1457
1458/**
1459 * Iterator callback for responding to join requests of a slave.
1460 */
1461static int
1462join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
1463 void *jh)
1464{
1465 struct JoinDecisionClosure *jcls = cls;
1466 // FIXME: add relays
1467 GNUNET_MULTICAST_join_decision (jh, jcls->is_admitted, 0, NULL, jcls->msg);
1468 return GNUNET_YES;
1469}
1470
1471
1472/**
1473 * Join decision from client.
1474 */
1475static void
1476handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1477 const struct GNUNET_MessageHeader *msg)
1478{
1479 struct Channel *
1480 ch = GNUNET_SERVER_client_get_user_context (client, struct Channel);
1481 GNUNET_assert (GNUNET_YES == ch->is_master);
1482 struct Master *mst = (struct Master *) ch;
1483
1484 struct MasterJoinDecision *dcsn = (struct MasterJoinDecision *) msg;
1485 struct JoinDecisionClosure jcls;
1486 jcls.is_admitted = dcsn->is_admitted;
1487 jcls.msg
1488 = (sizeof (*dcsn) + sizeof (struct GNUNET_PSYC_MessageHeader)
1489 <= ntohs (msg->size))
1490 ? (struct GNUNET_MessageHeader *) &dcsn[1]
1491 : NULL;
1492
1493 struct GNUNET_HashCode slave_key_hash;
1494 GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key),
1495 &slave_key_hash);
1496 GNUNET_CONTAINER_multihashmap_get_multiple (mst->join_reqs, &slave_key_hash,
1497 &join_decision_cb, &jcls);
1406 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1498 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1407} 1499}
1408 1500
@@ -1515,7 +1607,7 @@ static void
1515master_transmit_message (struct Master *mst) 1607master_transmit_message (struct Master *mst)
1516{ 1608{
1517 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p master_transmit_message()\n", mst); 1609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p master_transmit_message()\n", mst);
1518 mst->channel.tmit_task = 0; 1610 mst->ch.tmit_task = 0;
1519 if (NULL == mst->tmit_handle) 1611 if (NULL == mst->tmit_handle)
1520 { 1612 {
1521 mst->tmit_handle 1613 mst->tmit_handle
@@ -1536,7 +1628,7 @@ master_transmit_message (struct Master *mst)
1536static void 1628static void
1537slave_transmit_message (struct Slave *slv) 1629slave_transmit_message (struct Slave *slv)
1538{ 1630{
1539 slv->channel.tmit_task = 0; 1631 slv->ch.tmit_task = 0;
1540 if (NULL == slv->tmit_handle) 1632 if (NULL == slv->tmit_handle)
1541 { 1633 {
1542 slv->tmit_handle 1634 slv->tmit_handle
@@ -1654,8 +1746,8 @@ static void
1654handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client, 1746handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1655 const struct GNUNET_MessageHeader *msg) 1747 const struct GNUNET_MessageHeader *msg)
1656{ 1748{
1657 struct Channel *ch 1749 struct Channel *
1658 = GNUNET_SERVER_client_get_user_context (client, struct Channel); 1750 ch = GNUNET_SERVER_client_get_user_context (client, struct Channel);
1659 GNUNET_assert (NULL != ch); 1751 GNUNET_assert (NULL != ch);
1660 1752
1661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1753 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1775,6 +1867,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1775 { &handle_slave_join, NULL, 1867 { &handle_slave_join, NULL,
1776 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN, 0 }, 1868 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN, 0 },
1777 1869
1870 { &handle_join_decision, NULL,
1871 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 },
1872
1778 { &handle_psyc_message, NULL, 1873 { &handle_psyc_message, NULL,
1779 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 }, 1874 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 },
1780 1875
diff --git a/src/psyc/psyc.h b/src/psyc/psyc.h
index ab7b35d40..47f2a0122 100644
--- a/src/psyc/psyc.h
+++ b/src/psyc/psyc.h
@@ -230,8 +230,7 @@ struct OperationResult
230struct MasterJoinRequest 230struct MasterJoinRequest
231{ 231{
232 /** 232 /**
233 * Types: 233 * Type: GNUNET_MESSAGE_TYPE_PSYC_MASTER_JOIN_REQUEST
234 * - GNUNET_MESSAGE_TYPE_PSYC_MASTER_JOIN_REQUEST
235 */ 234 */
236 struct GNUNET_MessageHeader header; 235 struct GNUNET_MessageHeader header;
237 /** 236 /**
@@ -242,6 +241,28 @@ struct MasterJoinRequest
242 /* Followed by struct GNUNET_MessageHeader join_request */ 241 /* Followed by struct GNUNET_MessageHeader join_request */
243}; 242};
244 243
244
245struct MasterJoinDecision
246{
247 /**
248 * Type: GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION
249 */
250 struct GNUNET_MessageHeader header;
251
252 /**
253 * Public key of the joining slave.
254 */
255 struct GNUNET_CRYPTO_EddsaPublicKey slave_key;
256
257 /**
258 * #GNUNET_YES if the slave was admitted.
259 */
260 uint8_t is_admitted;
261
262 /* Followed by struct GNUNET_MessageHeader join_response */
263};
264
265
245GNUNET_NETWORK_STRUCT_END 266GNUNET_NETWORK_STRUCT_END
246 267
247#endif 268#endif
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c
index 62f099166..82ff18347 100644
--- a/src/psyc/psyc_api.c
+++ b/src/psyc/psyc_api.c
@@ -45,6 +45,7 @@ struct MessageQueue
45{ 45{
46 struct MessageQueue *prev; 46 struct MessageQueue *prev;
47 struct MessageQueue *next; 47 struct MessageQueue *next;
48 /* Followed by struct GNUNET_MessageHeader msg */
48}; 49};
49 50
50 51
@@ -222,7 +223,8 @@ struct GNUNET_PSYC_Slave
222 */ 223 */
223struct GNUNET_PSYC_JoinHandle 224struct GNUNET_PSYC_JoinHandle
224{ 225{
225 226 struct GNUNET_PSYC_Master *mst;
227 struct GNUNET_CRYPTO_EddsaPublicKey slave_key;
226}; 228};
227 229
228 230
@@ -912,11 +914,15 @@ static void
912handle_psyc_join_request (struct GNUNET_PSYC_Master *mst, 914handle_psyc_join_request (struct GNUNET_PSYC_Master *mst,
913 const struct MasterJoinRequest *req) 915 const struct MasterJoinRequest *req)
914{ 916{
915 // FIXME: extract join message from req[1] 917 struct GNUNET_PSYC_MessageHeader *msg = NULL;
916 const char *method_name = "_fixme"; 918 if (ntohs (req->header.size) <= sizeof (*req) + sizeof (*msg))
919 msg = (struct GNUNET_PSYC_MessageHeader *) &req[1];
920
917 struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh)); 921 struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh));
918 mst->join_cb (mst->ch.cb_cls, &req->slave_key, method_name, 922 jh->mst = mst;
919 0, NULL, NULL, 0, jh); 923 jh->slave_key = req->slave_key;
924
925 mst->join_cb (mst->ch.cb_cls, &req->slave_key, msg, jh);
920} 926}
921 927
922 928
@@ -931,7 +937,6 @@ static void
931message_handler (void *cls, 937message_handler (void *cls,
932 const struct GNUNET_MessageHeader *msg) 938 const struct GNUNET_MessageHeader *msg)
933{ 939{
934 // YUCK! => please have disjoint message handlers...
935 struct GNUNET_PSYC_Channel *ch = cls; 940 struct GNUNET_PSYC_Channel *ch = cls;
936 struct GNUNET_PSYC_Master *mst = cls; 941 struct GNUNET_PSYC_Master *mst = cls;
937 struct GNUNET_PSYC_Slave *slv = cls; 942 struct GNUNET_PSYC_Slave *slv = cls;
@@ -1264,7 +1269,33 @@ GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
1264 const void *data, 1269 const void *data,
1265 size_t data_size) 1270 size_t data_size)
1266{ 1271{
1267 1272 struct GNUNET_PSYC_Channel *ch = &jh->mst->ch;
1273
1274 struct MasterJoinDecision *dcsn;
1275 struct GNUNET_PSYC_MessageHeader *pmsg;
1276 uint16_t pmsg_size = 0;
1277/* FIXME:
1278 sizeof (*pmsg)
1279 + sizeof (struct GNUNET_PSYC_MessageMethod)
1280 + vars_size
1281 + sizeof (struct GNUNET_MessageHeader) + data_size
1282 + sizeof (struct GNUNET_MessageHeader);
1283*/
1284 uint16_t relay_size = relay_count * sizeof (*relays);
1285 struct MessageQueue *
1286 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn) + relay_size + pmsg_size);
1287 dcsn = (struct MasterJoinDecision *) &mq[1];
1288 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION);
1289 dcsn->header.size = htons (sizeof (*mq) + sizeof (*dcsn)
1290 + relay_size + pmsg_size);
1291 dcsn->is_admitted = (GNUNET_YES == is_admitted) ? GNUNET_YES : GNUNET_NO;
1292 dcsn->slave_key = jh->slave_key;
1293
1294 /* FIXME: add message parts to pmsg */
1295 memcpy (&dcsn[1], pmsg, pmsg_size);
1296
1297 GNUNET_CONTAINER_DLL_insert_tail (ch->tmit_head, ch->tmit_tail, mq);
1298 transmit_next (ch);
1268} 1299}
1269 1300
1270 1301
diff --git a/src/psyc/psyc_common.c b/src/psyc/psyc_common.c
index 74729aca2..af9cc0c6f 100644
--- a/src/psyc/psyc_common.c
+++ b/src/psyc/psyc_common.c
@@ -88,7 +88,7 @@ GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind,
88 { 88 {
89 struct GNUNET_PSYC_MessageHeader *pmsg 89 struct GNUNET_PSYC_MessageHeader *pmsg
90 = (struct GNUNET_PSYC_MessageHeader *) msg; 90 = (struct GNUNET_PSYC_MessageHeader *) msg;
91 GNUNET_log (kind, "\tID: %" PRIu64 "\tflags: %" PRIu32 "\n", 91 GNUNET_log (kind, "\tID: %" PRIu64 "\tflags: %x" PRIu32 "\n",
92 GNUNET_ntohll (pmsg->message_id), ntohl (pmsg->flags)); 92 GNUNET_ntohll (pmsg->message_id), ntohl (pmsg->flags));
93 break; 93 break;
94 } 94 }
diff --git a/src/psyc/test_psyc.c b/src/psyc/test_psyc.c
index cef8a5dcf..4195e464b 100644
--- a/src/psyc/test_psyc.c
+++ b/src/psyc/test_psyc.c
@@ -54,7 +54,6 @@ static GNUNET_SCHEDULER_TaskIdentifier end_badly_task;
54 54
55static struct GNUNET_PSYC_Master *mst; 55static struct GNUNET_PSYC_Master *mst;
56static struct GNUNET_PSYC_Slave *slv; 56static struct GNUNET_PSYC_Slave *slv;
57static struct GNUNET_PSYC_Channel *ch;
58 57
59static struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key; 58static struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
60static struct GNUNET_CRYPTO_EddsaPrivateKey *slave_key; 59static struct GNUNET_CRYPTO_EddsaPrivateKey *slave_key;
@@ -183,7 +182,7 @@ master_message (void *cls, uint64_t message_id, uint32_t flags,
183 182
184 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 183 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
185 "Master got message part of type %u and size %u " 184 "Master got message part of type %u and size %u "
186 "belonging to message ID %llu with flags %bu\n", 185 "belonging to message ID %llu with flags %xu\n",
187 type, size, message_id, flags); 186 type, size, message_id, flags);
188 187
189 switch (test) 188 switch (test)
@@ -192,7 +191,7 @@ master_message (void *cls, uint64_t message_id, uint32_t flags,
192 if (GNUNET_PSYC_MESSAGE_REQUEST != flags) 191 if (GNUNET_PSYC_MESSAGE_REQUEST != flags)
193 { 192 {
194 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
195 "Unexpected request flags: %lu\n", flags); 194 "Unexpected request flags: %x" PRIu32 "\n", flags);
196 GNUNET_assert (0); 195 GNUNET_assert (0);
197 return; 196 return;
198 } 197 }
@@ -227,7 +226,7 @@ slave_message (void *cls, uint64_t message_id, uint32_t flags,
227 226
228 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 227 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
229 "Slave got message part of type %u and size %u " 228 "Slave got message part of type %u and size %u "
230 "belonging to message ID %llu with flags %bu\n", 229 "belonging to message ID %llu with flags %xu\n",
231 type, size, message_id, flags); 230 type, size, message_id, flags);
232 231
233 switch (test) 232 switch (test)
@@ -245,15 +244,18 @@ slave_message (void *cls, uint64_t message_id, uint32_t flags,
245 244
246static void 245static void
247join_request (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 246join_request (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
248 const char *method_name, 247 const struct GNUNET_PSYC_MessageHeader *msg,
249 size_t variable_count, const struct GNUNET_ENV_Modifier *variables,
250 const void *data, size_t data_size,
251 struct GNUNET_PSYC_JoinHandle *jh) 248 struct GNUNET_PSYC_JoinHandle *jh)
252{ 249{
250 struct GNUNET_HashCode slave_key_hash;
251 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
253 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 252 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
254 "Got join request: %s (%zu vars)", method_name, variable_count); 253 "Got join request from %s.\n",
254 GNUNET_h2s (&slave_key_hash));
255
255 GNUNET_PSYC_join_decision (jh, GNUNET_YES, 0, NULL, "_notice_join", NULL, 256 GNUNET_PSYC_join_decision (jh, GNUNET_YES, 0, NULL, "_notice_join", NULL,
256 "you're in", 9); 257 "you're in", 9);
258 // FIXME: also test refusing entry
257} 259}
258 260
259 261
@@ -425,9 +427,8 @@ slave_join ()
425 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, 427 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
426 "_foo_bar", "foo bar baz", 11); 428 "_foo_bar", "foo bar baz", 11);
427 slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin, 429 slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin,
428 16, relays, &slave_message, &join_request, 430 16, relays, &slave_message, &slave_joined, NULL,
429 &slave_joined, NULL, "_request_join", env, 431 "_request_join", env, "some data", 9);
430 "some data", 9);
431 GNUNET_ENV_environment_destroy (env); 432 GNUNET_ENV_environment_destroy (env);
432} 433}
433 434