aboutsummaryrefslogtreecommitdiff
path: root/src/psyc
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/psyc
parent1cfab01aaea932539c39dcb2118ec4d6c6d44381 (diff)
downloadgnunet-83495695331fcfa8824d7a6d407b82cfcfc8b13c.tar.gz
gnunet-83495695331fcfa8824d7a6d407b82cfcfc8b13c.zip
psyc, multicast: join decision, tests
Diffstat (limited to 'src/psyc')
-rw-r--r--src/psyc/gnunet-service-psyc.c261
-rw-r--r--src/psyc/psyc.h19
-rw-r--r--src/psyc/psyc_api.c147
-rw-r--r--src/psyc/test_psyc.c86
4 files changed, 351 insertions, 162 deletions
diff --git a/src/psyc/gnunet-service-psyc.c b/src/psyc/gnunet-service-psyc.c
index 2b9ee7135..cef89b828 100644
--- a/src/psyc/gnunet-service-psyc.c
+++ b/src/psyc/gnunet-service-psyc.c
@@ -387,6 +387,11 @@ struct Slave
387 struct GNUNET_MessageHeader *join_req; 387 struct GNUNET_MessageHeader *join_req;
388 388
389 /** 389 /**
390 * Join decision received from multicast.
391 */
392 struct SlaveJoinDecision *join_dcsn;
393
394 /**
390 * Maximum request ID for this channel. 395 * Maximum request ID for this channel.
391 */ 396 */
392 uint64_t max_request_id; 397 uint64_t max_request_id;
@@ -397,6 +402,10 @@ static inline void
397transmit_message (struct Channel *ch); 402transmit_message (struct Channel *ch);
398 403
399 404
405static uint64_t
406message_queue_drop (struct Channel *ch);
407
408
400/** 409/**
401 * Task run during shutdown. 410 * Task run during shutdown.
402 * 411 *
@@ -413,7 +422,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
413 } 422 }
414 if (NULL != stats) 423 if (NULL != stats)
415 { 424 {
416 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 425 GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
417 stats = NULL; 426 stats = NULL;
418 } 427 }
419} 428}
@@ -471,7 +480,8 @@ cleanup_slave (struct Slave *slv)
471static void 480static void
472cleanup_channel (struct Channel *ch) 481cleanup_channel (struct Channel *ch)
473{ 482{
474 /* FIXME: fragment_cache_clear */ 483 message_queue_drop (ch);
484 GNUNET_CONTAINER_multihashmap_remove_all (recv_cache, &ch->pub_key_hash);
475 485
476 if (NULL != ch->store_op) 486 if (NULL != ch->store_op)
477 GNUNET_PSYCSTORE_operation_cancel (ch->store_op); 487 GNUNET_PSYCSTORE_operation_cancel (ch->store_op);
@@ -570,7 +580,7 @@ struct JoinMemTestClosure
570 580
571 581
572/** 582/**
573 * Membership test result callback used for join requests.m 583 * Membership test result callback used for join requests.
574 */ 584 */
575static void 585static void
576join_mem_test_cb (void *cls, int64_t result, const char *err_msg) 586join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
@@ -585,8 +595,7 @@ join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
585 &slave_key_hash); 595 &slave_key_hash);
586 GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh, 596 GNUNET_CONTAINER_multihashmap_put (mst->join_reqs, &slave_key_hash, jcls->jh,
587 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 597 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
588 msg_to_clients (jcls->ch, 598 msg_to_clients (jcls->ch, &jcls->master_join_req->header);
589 (struct GNUNET_MessageHeader *) jcls->master_join_req);
590 } 599 }
591 else 600 else
592 { 601 {
@@ -602,9 +611,10 @@ join_mem_test_cb (void *cls, int64_t result, const char *err_msg)
602 * Incoming join request from multicast. 611 * Incoming join request from multicast.
603 */ 612 */
604static void 613static void
605join_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 614mcast_join_request_cb (void *cls,
606 const struct GNUNET_MessageHeader *join_msg, 615 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
607 struct GNUNET_MULTICAST_JoinHandle *jh) 616 const struct GNUNET_MessageHeader *join_msg,
617 struct GNUNET_MULTICAST_JoinHandle *jh)
608{ 618{
609 struct Channel *ch = cls; 619 struct Channel *ch = cls;
610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join request.\n", ch); 620 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Got join request.\n", ch);
@@ -643,21 +653,58 @@ join_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
643} 653}
644 654
645 655
656/**
657 * Join decision received from multicast.
658 */
659static void
660mcast_join_decision_cb (void *cls, int is_admitted,
661 const struct GNUNET_PeerIdentity *peer,
662 uint16_t relay_count,
663 const struct GNUNET_PeerIdentity *relays,
664 const struct GNUNET_MessageHeader *join_resp)
665{
666 struct Slave *slv = cls;
667 struct Channel *ch = &slv->ch;
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
669 "%p Got join decision: %d\n", slv, is_admitted);
670
671 uint16_t join_resp_size = (NULL != join_resp) ? ntohs (join_resp->size) : 0;
672 struct SlaveJoinDecision *
673 dcsn = slv->join_dcsn = GNUNET_malloc (sizeof (*dcsn) + join_resp_size);
674 dcsn->header.size = htons (sizeof (*dcsn) + join_resp_size);
675 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION);
676 dcsn->is_admitted = htonl (is_admitted);
677 if (0 < join_resp_size)
678 memcpy (&dcsn[1], join_resp, join_resp_size);
679
680 msg_to_clients (ch, &dcsn->header);
681
682 if (GNUNET_YES == is_admitted)
683 {
684 ch->ready = GNUNET_YES;
685 }
686 else
687 {
688 slv->member = NULL;
689 }
690}
691
692
646static void 693static void
647membership_test_cb (void *cls, 694mcast_membership_test_cb (void *cls,
648 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 695 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
649 uint64_t message_id, uint64_t group_generation, 696 uint64_t message_id, uint64_t group_generation,
650 struct GNUNET_MULTICAST_MembershipTestHandle *mth) 697 struct GNUNET_MULTICAST_MembershipTestHandle *mth)
651{ 698{
652 699
653} 700}
654 701
655 702
656static void 703static void
657replay_fragment_cb (void *cls, 704mcast_replay_fragment_cb (void *cls,
658 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 705 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
659 uint64_t fragment_id, uint64_t flags, 706 uint64_t fragment_id, uint64_t flags,
660 struct GNUNET_MULTICAST_ReplayHandle *rh) 707 struct GNUNET_MULTICAST_ReplayHandle *rh)
661 708
662{ 709{
663 710
@@ -665,12 +712,12 @@ replay_fragment_cb (void *cls,
665 712
666 713
667static void 714static void
668replay_message_cb (void *cls, 715mcast_replay_message_cb (void *cls,
669 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 716 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
670 uint64_t message_id, 717 uint64_t message_id,
671 uint64_t fragment_offset, 718 uint64_t fragment_offset,
672 uint64_t flags, 719 uint64_t flags,
673 struct GNUNET_MULTICAST_ReplayHandle *rh) 720 struct GNUNET_MULTICAST_ReplayHandle *rh)
674{ 721{
675 722
676} 723}
@@ -744,7 +791,7 @@ mmsg_to_clients (struct Channel *ch,
744 pmsg->message_id = mmsg->message_id; 791 pmsg->message_id = mmsg->message_id;
745 792
746 memcpy (&pmsg[1], &mmsg[1], size - sizeof (*mmsg)); 793 memcpy (&pmsg[1], &mmsg[1], size - sizeof (*mmsg));
747 msg_to_clients (ch, (const struct GNUNET_MessageHeader *) pmsg); 794 msg_to_clients (ch, &pmsg->header);
748 GNUNET_free (pmsg); 795 GNUNET_free (pmsg);
749} 796}
750 797
@@ -988,6 +1035,7 @@ fragment_queue_run (struct Channel *ch, uint64_t msg_id,
988 * has already been delivered to the client. 1035 * has already been delivered to the client.
989 * 1036 *
990 * @param ch Channel. 1037 * @param ch Channel.
1038 *
991 * @return Number of messages removed from queue and sent to client. 1039 * @return Number of messages removed from queue and sent to client.
992 */ 1040 */
993static uint64_t 1041static uint64_t
@@ -1061,6 +1109,43 @@ message_queue_run (struct Channel *ch)
1061 1109
1062 1110
1063/** 1111/**
1112 * Drop message queue of a channel.
1113 *
1114 * Remove all messages in queue without sending it to clients.
1115 *
1116 * @param ch Channel.
1117 *
1118 * @return Number of messages removed from queue.
1119 */
1120static uint64_t
1121message_queue_drop (struct Channel *ch)
1122{
1123 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1124 "%p Dropping message queue.\n", ch);
1125 uint64_t n = 0;
1126 uint64_t msg_id;
1127 while (GNUNET_YES == GNUNET_CONTAINER_heap_peek2 (ch->recv_msgs, NULL,
1128 &msg_id))
1129 {
1130 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1131 "%p Dropping message %" PRIu64 " from queue.\n", ch, msg_id);
1132 struct GNUNET_HashCode msg_id_hash;
1133 hash_key_from_hll (&msg_id_hash, msg_id);
1134
1135 struct FragmentQueue *
1136 fragq = GNUNET_CONTAINER_multihashmap_get (ch->recv_frags, &msg_id_hash);
1137
1138 fragment_queue_run (ch, msg_id, fragq, GNUNET_YES);
1139 GNUNET_CONTAINER_heap_remove_root (ch->recv_msgs);
1140 n++;
1141 }
1142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1143 "%p Removed %" PRIu64 " messages from queue.\n", ch, n);
1144 return n;
1145}
1146
1147
1148/**
1064 * Handle incoming message from multicast. 1149 * Handle incoming message from multicast.
1065 * 1150 *
1066 * @param ch Channel. 1151 * @param ch Channel.
@@ -1069,7 +1154,7 @@ message_queue_run (struct Channel *ch)
1069 * @return #GNUNET_OK or #GNUNET_SYSERR 1154 * @return #GNUNET_OK or #GNUNET_SYSERR
1070 */ 1155 */
1071static int 1156static int
1072handle_multicast_message (struct Channel *ch, 1157client_multicast_message (struct Channel *ch,
1073 const struct GNUNET_MULTICAST_MessageHeader *mmsg) 1158 const struct GNUNET_MULTICAST_MessageHeader *mmsg)
1074{ 1159{
1075 GNUNET_PSYCSTORE_fragment_store (store, &ch->pub_key, mmsg, 0, NULL, NULL); 1160 GNUNET_PSYCSTORE_fragment_store (store, &ch->pub_key, mmsg, 0, NULL, NULL);
@@ -1106,7 +1191,7 @@ handle_multicast_message (struct Channel *ch,
1106 * Store it using PSYCstore and send it to the client of the channel. 1191 * Store it using PSYCstore and send it to the client of the channel.
1107 */ 1192 */
1108static void 1193static void
1109message_cb (void *cls, const struct GNUNET_MessageHeader *msg) 1194mcast_message_cb (void *cls, const struct GNUNET_MessageHeader *msg)
1110{ 1195{
1111 struct Channel *ch = cls; 1196 struct Channel *ch = cls;
1112 uint16_t type = ntohs (msg->type); 1197 uint16_t type = ntohs (msg->type);
@@ -1120,7 +1205,7 @@ message_cb (void *cls, const struct GNUNET_MessageHeader *msg)
1120 { 1205 {
1121 case GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE: 1206 case GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE:
1122 { 1207 {
1123 handle_multicast_message (ch, (const struct 1208 client_multicast_message (ch, (const struct
1124 GNUNET_MULTICAST_MessageHeader *) msg); 1209 GNUNET_MULTICAST_MessageHeader *) msg);
1125 break; 1210 break;
1126 } 1211 }
@@ -1141,9 +1226,10 @@ message_cb (void *cls, const struct GNUNET_MessageHeader *msg)
1141 * @param flags Request flags. 1226 * @param flags Request flags.
1142 */ 1227 */
1143static void 1228static void
1144request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key, 1229mcast_request_cb (void *cls,
1145 const struct GNUNET_MessageHeader *msg, 1230 const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
1146 enum GNUNET_MULTICAST_MessageFlags flags) 1231 const struct GNUNET_MessageHeader *msg,
1232 enum GNUNET_MULTICAST_MessageFlags flags)
1147{ 1233{
1148 struct Master *mst = cls; 1234 struct Master *mst = cls;
1149 struct Channel *ch = &mst->ch; 1235 struct Channel *ch = &mst->ch;
@@ -1183,7 +1269,7 @@ request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
1183 pmsg->flags = htonl (GNUNET_PSYC_MESSAGE_REQUEST); 1269 pmsg->flags = htonl (GNUNET_PSYC_MESSAGE_REQUEST);
1184 1270
1185 memcpy (&pmsg[1], &req[1], size - sizeof (*req)); 1271 memcpy (&pmsg[1], &req[1], size - sizeof (*req));
1186 msg_to_clients (ch, (const struct GNUNET_MessageHeader *) pmsg); 1272 msg_to_clients (ch, &pmsg->header);
1187 GNUNET_free (pmsg); 1273 GNUNET_free (pmsg);
1188 break; 1274 break;
1189 } 1275 }
@@ -1221,11 +1307,13 @@ master_counters_cb (void *cls, int result, uint64_t max_fragment_id,
1221 ch->max_state_message_id = max_state_message_id; 1307 ch->max_state_message_id = max_state_message_id;
1222 mst->max_group_generation = max_group_generation; 1308 mst->max_group_generation = max_group_generation;
1223 mst->origin 1309 mst->origin
1224 = GNUNET_MULTICAST_origin_start (cfg, &mst->priv_key, 1310 = GNUNET_MULTICAST_origin_start (cfg, &mst->priv_key, max_fragment_id,
1225 max_fragment_id, 1311 &mcast_join_request_cb,
1226 join_cb, membership_test_cb, 1312 &mcast_membership_test_cb,
1227 replay_fragment_cb, replay_message_cb, 1313 &mcast_replay_fragment_cb,
1228 request_cb, message_cb, ch); 1314 &mcast_replay_message_cb,
1315 &mcast_request_cb,
1316 &mcast_message_cb, ch);
1229 ch->ready = GNUNET_YES; 1317 ch->ready = GNUNET_YES;
1230 } 1318 }
1231 else 1319 else
@@ -1266,11 +1354,13 @@ slave_counters_cb (void *cls, int result, uint64_t max_fragment_id,
1266 = GNUNET_MULTICAST_member_join (cfg, &ch->pub_key, &slv->priv_key, 1354 = GNUNET_MULTICAST_member_join (cfg, &ch->pub_key, &slv->priv_key,
1267 &slv->origin, 1355 &slv->origin,
1268 slv->relay_count, slv->relays, 1356 slv->relay_count, slv->relays,
1269 slv->join_req, join_cb, 1357 slv->join_req,
1270 membership_test_cb, 1358 &mcast_join_request_cb,
1271 replay_fragment_cb, replay_message_cb, 1359 &mcast_join_decision_cb,
1272 message_cb, ch); 1360 &mcast_membership_test_cb,
1273 ch->ready = GNUNET_YES; 1361 &mcast_replay_fragment_cb,
1362 &mcast_replay_message_cb,
1363 &mcast_message_cb, ch);
1274 } 1364 }
1275 else 1365 else
1276 { 1366 {
@@ -1297,7 +1387,7 @@ channel_init (struct Channel *ch)
1297 * Handle a connecting client starting a channel master. 1387 * Handle a connecting client starting a channel master.
1298 */ 1388 */
1299static void 1389static void
1300handle_master_start (void *cls, struct GNUNET_SERVER_Client *client, 1390client_master_start (void *cls, struct GNUNET_SERVER_Client *client,
1301 const struct GNUNET_MessageHeader *msg) 1391 const struct GNUNET_MessageHeader *msg)
1302{ 1392{
1303 const struct MasterStartRequest *req 1393 const struct MasterStartRequest *req
@@ -1363,7 +1453,7 @@ handle_master_start (void *cls, struct GNUNET_SERVER_Client *client,
1363 * Handle a connecting client joining as a channel slave. 1453 * Handle a connecting client joining as a channel slave.
1364 */ 1454 */
1365static void 1455static void
1366handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client, 1456client_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1367 const struct GNUNET_MessageHeader *msg) 1457 const struct GNUNET_MessageHeader *msg)
1368{ 1458{
1369 const struct SlaveJoinRequest *req 1459 const struct SlaveJoinRequest *req
@@ -1389,6 +1479,8 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1389 { 1479 {
1390 slv = GNUNET_new (struct Slave); 1480 slv = GNUNET_new (struct Slave);
1391 slv->priv_key = req->slave_key; 1481 slv->priv_key = req->slave_key;
1482 slv->pub_key = slv_pub_key;
1483 slv->pub_key_hash = slv_pub_key_hash;
1392 slv->origin = req->origin; 1484 slv->origin = req->origin;
1393 slv->relay_count = ntohl (req->relay_count); 1485 slv->relay_count = ntohl (req->relay_count);
1394 if (0 < slv->relay_count) 1486 if (0 < slv->relay_count)
@@ -1411,10 +1503,10 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1411 if (NULL == ch_slv) 1503 if (NULL == ch_slv)
1412 { 1504 {
1413 ch_slv = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 1505 ch_slv = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1414 GNUNET_CONTAINER_multihashmap_put (channel_slaves, &pub_key_hash, ch_slv, 1506 GNUNET_CONTAINER_multihashmap_put (channel_slaves, &ch->pub_key_hash, ch_slv,
1415 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1507 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1416 } 1508 }
1417 GNUNET_CONTAINER_multihashmap_put (ch_slv, &slv_pub_key_hash, ch, 1509 GNUNET_CONTAINER_multihashmap_put (ch_slv, &slv->pub_key_hash, ch,
1418 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1510 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1419 GNUNET_CONTAINER_multihashmap_put (slaves, &ch->pub_key_hash, ch, 1511 GNUNET_CONTAINER_multihashmap_put (slaves, &ch->pub_key_hash, ch,
1420 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1512 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -1434,6 +1526,29 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1434 GNUNET_SERVER_notification_context_add (nc, client); 1526 GNUNET_SERVER_notification_context_add (nc, client);
1435 GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, 1527 GNUNET_SERVER_notification_context_unicast (nc, client, &res.header,
1436 GNUNET_NO); 1528 GNUNET_NO);
1529
1530 if (NULL == slv->member)
1531 {
1532 slv->member
1533 = GNUNET_MULTICAST_member_join (cfg, &ch->pub_key, &slv->priv_key,
1534 &slv->origin,
1535 slv->relay_count, slv->relays,
1536 slv->join_req,
1537 &mcast_join_request_cb,
1538 &mcast_join_decision_cb,
1539 &mcast_membership_test_cb,
1540 &mcast_replay_fragment_cb,
1541 &mcast_replay_message_cb,
1542 &mcast_message_cb, ch);
1543
1544 }
1545 else if (NULL != slv->join_dcsn)
1546 {
1547 GNUNET_SERVER_notification_context_add (nc, client);
1548 GNUNET_SERVER_notification_context_unicast (nc, client,
1549 &slv->join_dcsn->header,
1550 GNUNET_NO);
1551 }
1437 } 1552 }
1438 1553
1439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1451,7 +1566,7 @@ handle_slave_join (void *cls, struct GNUNET_SERVER_Client *client,
1451 1566
1452struct JoinDecisionClosure 1567struct JoinDecisionClosure
1453{ 1568{
1454 uint8_t is_admitted; 1569 int32_t is_admitted;
1455 struct GNUNET_MessageHeader *msg; 1570 struct GNUNET_MessageHeader *msg;
1456}; 1571};
1457 1572
@@ -1460,8 +1575,8 @@ struct JoinDecisionClosure
1460 * Iterator callback for responding to join requests of a slave. 1575 * Iterator callback for responding to join requests of a slave.
1461 */ 1576 */
1462static int 1577static int
1463join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash, 1578send_join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
1464 void *jh) 1579 void *jh)
1465{ 1580{
1466 struct JoinDecisionClosure *jcls = cls; 1581 struct JoinDecisionClosure *jcls = cls;
1467 // FIXME: add relays 1582 // FIXME: add relays
@@ -1474,7 +1589,7 @@ join_decision_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
1474 * Join decision from client. 1589 * Join decision from client.
1475 */ 1590 */
1476static void 1591static void
1477handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client, 1592client_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1478 const struct GNUNET_MessageHeader *msg) 1593 const struct GNUNET_MessageHeader *msg)
1479{ 1594{
1480 struct Channel * 1595 struct Channel *
@@ -1484,7 +1599,7 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1484 1599
1485 struct MasterJoinDecision *dcsn = (struct MasterJoinDecision *) msg; 1600 struct MasterJoinDecision *dcsn = (struct MasterJoinDecision *) msg;
1486 struct JoinDecisionClosure jcls; 1601 struct JoinDecisionClosure jcls;
1487 jcls.is_admitted = dcsn->is_admitted; 1602 jcls.is_admitted = ntohl (dcsn->is_admitted);
1488 jcls.msg 1603 jcls.msg
1489 = (sizeof (*dcsn) + sizeof (struct GNUNET_PSYC_MessageHeader) 1604 = (sizeof (*dcsn) + sizeof (struct GNUNET_PSYC_MessageHeader)
1490 <= ntohs (msg->size)) 1605 <= ntohs (msg->size))
@@ -1494,8 +1609,17 @@ handle_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
1494 struct GNUNET_HashCode slave_key_hash; 1609 struct GNUNET_HashCode slave_key_hash;
1495 GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key), 1610 GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key),
1496 &slave_key_hash); 1611 &slave_key_hash);
1612
1613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1614 "%p Got join decision (%d) from client for channel %s..\n",
1615 mst, jcls.is_admitted, GNUNET_h2s (&ch->pub_key_hash));
1616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1617 "%p ..and slave %s.\n",
1618 mst, GNUNET_h2s (&slave_key_hash));
1619
1497 GNUNET_CONTAINER_multihashmap_get_multiple (mst->join_reqs, &slave_key_hash, 1620 GNUNET_CONTAINER_multihashmap_get_multiple (mst->join_reqs, &slave_key_hash,
1498 &join_decision_cb, &jcls); 1621 &send_join_decision_cb, &jcls);
1622 GNUNET_CONTAINER_multihashmap_remove_all (mst->join_reqs, &slave_key_hash);
1499 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1623 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1500} 1624}
1501 1625
@@ -1758,10 +1882,10 @@ transmit_cancel (struct Channel *ch, struct GNUNET_SERVER_Client *client)
1758 1882
1759 1883
1760/** 1884/**
1761 * Incoming message from a client. 1885 * Incoming message from a master or slave client.
1762 */ 1886 */
1763static void 1887static void
1764handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client, 1888client_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1765 const struct GNUNET_MessageHeader *msg) 1889 const struct GNUNET_MessageHeader *msg)
1766{ 1890{
1767 struct Channel * 1891 struct Channel *
@@ -1775,8 +1899,7 @@ handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1775 if (GNUNET_YES != ch->ready) 1899 if (GNUNET_YES != ch->ready)
1776 { 1900 {
1777 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1901 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1778 "%p Dropping message from client, channel is not ready yet.\n", 1902 "%p Channel is not ready, dropping message from client.\n", ch);
1779 ch);
1780 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1903 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1781 return; 1904 return;
1782 } 1905 }
@@ -1784,7 +1907,7 @@ handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1784 uint16_t size = ntohs (msg->size); 1907 uint16_t size = ntohs (msg->size);
1785 if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < size - sizeof (*msg)) 1908 if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD < size - sizeof (*msg))
1786 { 1909 {
1787 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%p Message payload too large\n", ch); 1910 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%p Message payload too large.\n", ch);
1788 GNUNET_break (0); 1911 GNUNET_break (0);
1789 transmit_cancel (ch, client); 1912 transmit_cancel (ch, client);
1790 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1913 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -1817,7 +1940,7 @@ handle_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
1817 * Client requests to add a slave to the membership database. 1940 * Client requests to add a slave to the membership database.
1818 */ 1941 */
1819static void 1942static void
1820handle_slave_add (void *cls, struct GNUNET_SERVER_Client *client, 1943client_slave_add (void *cls, struct GNUNET_SERVER_Client *client,
1821 const struct GNUNET_MessageHeader *msg) 1944 const struct GNUNET_MessageHeader *msg)
1822{ 1945{
1823 1946
@@ -1828,7 +1951,7 @@ handle_slave_add (void *cls, struct GNUNET_SERVER_Client *client,
1828 * Client requests to remove a slave from the membership database. 1951 * Client requests to remove a slave from the membership database.
1829 */ 1952 */
1830static void 1953static void
1831handle_slave_remove (void *cls, struct GNUNET_SERVER_Client *client, 1954client_slave_remove (void *cls, struct GNUNET_SERVER_Client *client,
1832 const struct GNUNET_MessageHeader *msg) 1955 const struct GNUNET_MessageHeader *msg)
1833{ 1956{
1834 1957
@@ -1839,7 +1962,7 @@ handle_slave_remove (void *cls, struct GNUNET_SERVER_Client *client,
1839 * Client requests channel history from PSYCstore. 1962 * Client requests channel history from PSYCstore.
1840 */ 1963 */
1841static void 1964static void
1842handle_story_request (void *cls, struct GNUNET_SERVER_Client *client, 1965client_story_request (void *cls, struct GNUNET_SERVER_Client *client,
1843 const struct GNUNET_MessageHeader *msg) 1966 const struct GNUNET_MessageHeader *msg)
1844{ 1967{
1845 1968
@@ -1850,7 +1973,7 @@ handle_story_request (void *cls, struct GNUNET_SERVER_Client *client,
1850 * Client requests best matching state variable from PSYCstore. 1973 * Client requests best matching state variable from PSYCstore.
1851 */ 1974 */
1852static void 1975static void
1853handle_state_get (void *cls, struct GNUNET_SERVER_Client *client, 1976client_state_get (void *cls, struct GNUNET_SERVER_Client *client,
1854 const struct GNUNET_MessageHeader *msg) 1977 const struct GNUNET_MessageHeader *msg)
1855{ 1978{
1856 1979
@@ -1861,7 +1984,7 @@ handle_state_get (void *cls, struct GNUNET_SERVER_Client *client,
1861 * Client requests state variables with a given prefix from PSYCstore. 1984 * Client requests state variables with a given prefix from PSYCstore.
1862 */ 1985 */
1863static void 1986static void
1864handle_state_get_prefix (void *cls, struct GNUNET_SERVER_Client *client, 1987client_state_get_prefix (void *cls, struct GNUNET_SERVER_Client *client,
1865 const struct GNUNET_MessageHeader *msg) 1988 const struct GNUNET_MessageHeader *msg)
1866{ 1989{
1867 1990
@@ -1880,31 +2003,31 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1880 const struct GNUNET_CONFIGURATION_Handle *c) 2003 const struct GNUNET_CONFIGURATION_Handle *c)
1881{ 2004{
1882 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 2005 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1883 { &handle_master_start, NULL, 2006 { &client_master_start, NULL,
1884 GNUNET_MESSAGE_TYPE_PSYC_MASTER_START, 0 }, 2007 GNUNET_MESSAGE_TYPE_PSYC_MASTER_START, 0 },
1885 2008
1886 { &handle_slave_join, NULL, 2009 { &client_slave_join, NULL,
1887 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN, 0 }, 2010 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN, 0 },
1888 2011
1889 { &handle_join_decision, NULL, 2012 { &client_join_decision, NULL,
1890 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 }, 2013 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 },
1891 2014
1892 { &handle_psyc_message, NULL, 2015 { &client_psyc_message, NULL,
1893 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 }, 2016 GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 },
1894 2017
1895 { &handle_slave_add, NULL, 2018 { &client_slave_add, NULL,
1896 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_ADD, 0 }, 2019 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_ADD, 0 },
1897 2020
1898 { &handle_slave_remove, NULL, 2021 { &client_slave_remove, NULL,
1899 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_RM, 0 }, 2022 GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_SLAVE_RM, 0 },
1900 2023
1901 { &handle_story_request, NULL, 2024 { &client_story_request, NULL,
1902 GNUNET_MESSAGE_TYPE_PSYC_STORY_REQUEST, 0 }, 2025 GNUNET_MESSAGE_TYPE_PSYC_STORY_REQUEST, 0 },
1903 2026
1904 { &handle_state_get, NULL, 2027 { &client_state_get, NULL,
1905 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET, 0 }, 2028 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET, 0 },
1906 2029
1907 { &handle_state_get_prefix, NULL, 2030 { &client_state_get_prefix, NULL,
1908 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 } 2031 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 }
1909 }; 2032 };
1910 2033
diff --git a/src/psyc/psyc.h b/src/psyc/psyc.h
index 47f2a0122..66c8de898 100644
--- a/src/psyc/psyc.h
+++ b/src/psyc/psyc.h
@@ -250,19 +250,36 @@ struct MasterJoinDecision
250 struct GNUNET_MessageHeader header; 250 struct GNUNET_MessageHeader header;
251 251
252 /** 252 /**
253 * #GNUNET_YES if the slave was admitted.
254 */
255 int32_t is_admitted;
256
257 /**
253 * Public key of the joining slave. 258 * Public key of the joining slave.
254 */ 259 */
255 struct GNUNET_CRYPTO_EddsaPublicKey slave_key; 260 struct GNUNET_CRYPTO_EddsaPublicKey slave_key;
256 261
262 /* Followed by struct GNUNET_MessageHeader join_response */
263};
264
265
266struct SlaveJoinDecision
267{
268 /**
269 * Type: GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION
270 */
271 struct GNUNET_MessageHeader header;
272
257 /** 273 /**
258 * #GNUNET_YES if the slave was admitted. 274 * #GNUNET_YES if the slave was admitted.
259 */ 275 */
260 uint8_t is_admitted; 276 int32_t is_admitted;
261 277
262 /* Followed by struct GNUNET_MessageHeader join_response */ 278 /* Followed by struct GNUNET_MessageHeader join_response */
263}; 279};
264 280
265 281
282
266GNUNET_NETWORK_STRUCT_END 283GNUNET_NETWORK_STRUCT_END
267 284
268#endif 285#endif
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c
index ee49a584f..7ec9d21b7 100644
--- a/src/psyc/psyc_api.c
+++ b/src/psyc/psyc_api.c
@@ -198,9 +198,9 @@ struct GNUNET_PSYC_Master
198 GNUNET_PSYC_MasterStartCallback start_cb; 198 GNUNET_PSYC_MasterStartCallback start_cb;
199 199
200 /** 200 /**
201 * Join handler callback. 201 * Join request callback.
202 */ 202 */
203 GNUNET_PSYC_JoinCallback join_cb; 203 GNUNET_PSYC_JoinRequestCallback join_req_cb;
204}; 204};
205 205
206 206
@@ -211,14 +211,16 @@ struct GNUNET_PSYC_Slave
211{ 211{
212 struct GNUNET_PSYC_Channel ch; 212 struct GNUNET_PSYC_Channel ch;
213 213
214 GNUNET_PSYC_SlaveJoinCallback join_cb; 214 GNUNET_PSYC_SlaveConnectCallback connect_cb;
215
216 GNUNET_PSYC_JoinDecisionCallback join_dcsn_cb;
215}; 217};
216 218
217 219
218/** 220/**
219 * Handle that identifies a join request. 221 * Handle that identifies a join request.
220 * 222 *
221 * Used to match calls to #GNUNET_PSYC_JoinCallback to the 223 * Used to match calls to #GNUNET_PSYC_JoinRequestCallback to the
222 * corresponding calls to GNUNET_PSYC_join_decision(). 224 * corresponding calls to GNUNET_PSYC_join_decision().
223 */ 225 */
224struct GNUNET_PSYC_JoinHandle 226struct GNUNET_PSYC_JoinHandle
@@ -922,7 +924,22 @@ handle_psyc_join_request (struct GNUNET_PSYC_Master *mst,
922 jh->mst = mst; 924 jh->mst = mst;
923 jh->slave_key = req->slave_key; 925 jh->slave_key = req->slave_key;
924 926
925 mst->join_cb (mst->ch.cb_cls, &req->slave_key, msg, jh); 927 if (NULL != mst->join_req_cb)
928 mst->join_req_cb (mst->ch.cb_cls, &req->slave_key, msg, jh);
929}
930
931
932static void
933handle_psyc_join_decision (struct GNUNET_PSYC_Slave *slv,
934 const struct SlaveJoinDecision *dcsn)
935{
936 struct GNUNET_PSYC_MessageHeader *msg = NULL;
937 if (ntohs (dcsn->header.size) <= sizeof (*dcsn) + sizeof (*msg))
938 msg = (struct GNUNET_PSYC_MessageHeader *) &dcsn[1];
939
940 struct GNUNET_PSYC_JoinHandle *jh = GNUNET_malloc (sizeof (*jh));
941 if (NULL != slv->join_dcsn_cb)
942 slv->join_dcsn_cb (slv->ch.cb_cls, ntohl (dcsn->is_admitted), msg);
926} 943}
927 944
928 945
@@ -971,6 +988,9 @@ message_handler (void *cls,
971 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST: 988 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST:
972 size_min = sizeof (struct MasterJoinRequest); 989 size_min = sizeof (struct MasterJoinRequest);
973 break; 990 break;
991 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION:
992 size_min = sizeof (struct SlaveJoinDecision);
993 break;
974 default: 994 default:
975 GNUNET_break_op (0); 995 GNUNET_break_op (0);
976 return; 996 return;
@@ -995,8 +1015,8 @@ message_handler (void *cls,
995 case GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK: 1015 case GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK:
996 { 1016 {
997 struct CountersResult *cres = (struct CountersResult *) msg; 1017 struct CountersResult *cres = (struct CountersResult *) msg;
998 if (NULL != slv->join_cb) 1018 if (NULL != slv->connect_cb)
999 slv->join_cb (ch->cb_cls, GNUNET_ntohll (cres->max_message_id)); 1019 slv->connect_cb (ch->cb_cls, GNUNET_ntohll (cres->max_message_id));
1000 break; 1020 break;
1001 } 1021 }
1002 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK: 1022 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK:
@@ -1013,6 +1033,11 @@ message_handler (void *cls,
1013 handle_psyc_join_request ((struct GNUNET_PSYC_Master *) ch, 1033 handle_psyc_join_request ((struct GNUNET_PSYC_Master *) ch,
1014 (const struct MasterJoinRequest *) msg); 1034 (const struct MasterJoinRequest *) msg);
1015 break; 1035 break;
1036
1037 case GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION:
1038 handle_psyc_join_decision ((struct GNUNET_PSYC_Slave *) ch,
1039 (const struct SlaveJoinDecision *) msg);
1040 break;
1016 } 1041 }
1017 1042
1018 if (NULL != ch->client) 1043 if (NULL != ch->client)
@@ -1175,20 +1200,20 @@ disconnect (void *c)
1175 * or part messages, the respective methods must call other PSYC functions to 1200 * or part messages, the respective methods must call other PSYC functions to
1176 * inform PSYC about the meaning of the respective events. 1201 * inform PSYC about the meaning of the respective events.
1177 * 1202 *
1178 * @param cfg Configuration to use (to connect to PSYC service). 1203 * @param cfg Configuration to use (to connect to PSYC service).
1179 * @param channel_key ECC key that will be used to sign messages for this 1204 * @param channel_key ECC key that will be used to sign messages for this
1180 * PSYC session. The public key is used to identify the PSYC channel. 1205 * PSYC session. The public key is used to identify the PSYC channel.
1181 * Note that end-users will usually not use the private key directly, but 1206 * Note that end-users will usually not use the private key directly, but
1182 * rather look it up in GNS for places managed by other users, or select 1207 * rather look it up in GNS for places managed by other users, or select
1183 * a file with the private key(s) when setting up their own channels 1208 * a file with the private key(s) when setting up their own channels
1184 * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper 1209 * FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
1185 * one in the future. 1210 * one in the future.
1186 * @param policy Channel policy specifying join and history restrictions. 1211 * @param policy Channel policy specifying join and history restrictions.
1187 * Used to automate join decisions. 1212 * Used to automate join decisions.
1188 * @param message_cb Function to invoke on message parts received from slaves. 1213 * @param message_cb Function to invoke on message parts received from slaves.
1189 * @param join_cb Function to invoke when a peer wants to join. 1214 * @param join_request_cb Function to invoke when a slave wants to join.
1190 * @param master_started_cb Function to invoke after the channel master started. 1215 * @param master_start_cb Function to invoke after the channel master started.
1191 * @param cls Closure for @a master_started_cb and @a join_cb. 1216 * @param cls Closure for @a method and @a join_cb.
1192 * 1217 *
1193 * @return Handle for the channel master, NULL on error. 1218 * @return Handle for the channel master, NULL on error.
1194 */ 1219 */
@@ -1196,9 +1221,9 @@ struct GNUNET_PSYC_Master *
1196GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 1221GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
1197 const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key, 1222 const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key,
1198 enum GNUNET_PSYC_Policy policy, 1223 enum GNUNET_PSYC_Policy policy,
1224 GNUNET_PSYC_MasterStartCallback start_cb,
1225 GNUNET_PSYC_JoinRequestCallback join_request_cb,
1199 GNUNET_PSYC_MessageCallback message_cb, 1226 GNUNET_PSYC_MessageCallback message_cb,
1200 GNUNET_PSYC_JoinCallback join_cb,
1201 GNUNET_PSYC_MasterStartCallback master_started_cb,
1202 void *cls) 1227 void *cls)
1203{ 1228{
1204 struct GNUNET_PSYC_Master *mst = GNUNET_malloc (sizeof (*mst)); 1229 struct GNUNET_PSYC_Master *mst = GNUNET_malloc (sizeof (*mst));
@@ -1210,8 +1235,8 @@ GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
1210 req->channel_key = *channel_key; 1235 req->channel_key = *channel_key;
1211 req->policy = policy; 1236 req->policy = policy;
1212 1237
1213 mst->start_cb = master_started_cb; 1238 mst->start_cb = start_cb;
1214 mst->join_cb = join_cb; 1239 mst->join_req_cb = join_request_cb;
1215 ch->message_cb = message_cb; 1240 ch->message_cb = message_cb;
1216 ch->cb_cls = cls; 1241 ch->cb_cls = cls;
1217 ch->cfg = cfg; 1242 ch->cfg = cfg;
@@ -1244,8 +1269,9 @@ GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master)
1244 * #GNUNET_PSYC_JoinCallback. 1269 * #GNUNET_PSYC_JoinCallback.
1245 * 1270 *
1246 * @param jh Join request handle. 1271 * @param jh Join request handle.
1247 * @param is_admitted #GNUNET_YES if joining is approved, 1272 * @param is_admitted #GNUNET_YES if the join is approved,
1248 * #GNUNET_NO if it is disapproved. 1273 * #GNUNET_NO if it is disapproved,
1274 * #GNUNET_SYSERR if we cannot answer the request.
1249 * @param relay_count Number of relays given. 1275 * @param relay_count Number of relays given.
1250 * @param relays Array of suggested peers that might be useful relays to use 1276 * @param relays Array of suggested peers that might be useful relays to use
1251 * when joining the multicast group (essentially a list of peers that 1277 * when joining the multicast group (essentially a list of peers that
@@ -1254,48 +1280,42 @@ GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master)
1254 * be the multicast origin) is a good candidate for building the 1280 * be the multicast origin) is a good candidate for building the
1255 * multicast tree. Note that it is unnecessary to specify our own 1281 * multicast tree. Note that it is unnecessary to specify our own
1256 * peer identity in this array. 1282 * peer identity in this array.
1257 * @param method_name Method name for the message transmitted with the response. 1283 * @param join_resp Application-dependent join response message.
1258 * @param env Environment containing transient variables for the message, or NULL. 1284 *
1259 * @param data Data of the message. 1285 * @return #GNUNET_OK on success,
1260 * @param data_size Size of @a data. 1286 * #GNUNET_SYSERR if the message is too large.
1261 */ 1287 */
1262void 1288int
1263GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh, 1289GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
1264 int is_admitted, 1290 int is_admitted,
1265 uint32_t relay_count, 1291 uint32_t relay_count,
1266 const struct GNUNET_PeerIdentity *relays, 1292 const struct GNUNET_PeerIdentity *relays,
1267 const char *method_name, 1293 const struct GNUNET_PSYC_MessageHeader *join_resp)
1268 const struct GNUNET_ENV_Environment *env,
1269 const void *data,
1270 size_t data_size)
1271{ 1294{
1272 struct GNUNET_PSYC_Channel *ch = &jh->mst->ch; 1295 struct GNUNET_PSYC_Channel *ch = &jh->mst->ch;
1273
1274 struct MasterJoinDecision *dcsn; 1296 struct MasterJoinDecision *dcsn;
1275 struct GNUNET_PSYC_MessageHeader *pmsg = NULL; 1297 uint16_t join_resp_size
1276 uint16_t pmsg_size = 0; 1298 = (NULL != join_resp) ? ntohs (join_resp->header.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); 1299 uint16_t relay_size = relay_count * sizeof (*relays);
1285 struct MessageQueue * 1300
1286 mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn) + relay_size + pmsg_size); 1301 if (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD
1302 < sizeof (*dcsn) + relay_size + join_resp_size)
1303 return GNUNET_SYSERR;
1304
1305 struct MessageQueue *mq = GNUNET_malloc (sizeof (*mq) + sizeof (*dcsn)
1306 + relay_size + join_resp_size);
1287 dcsn = (struct MasterJoinDecision *) &mq[1]; 1307 dcsn = (struct MasterJoinDecision *) &mq[1];
1288 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + pmsg_size); 1308 dcsn->header.size = htons (sizeof (*dcsn) + relay_size + join_resp_size);
1289 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION); 1309 dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION);
1290 dcsn->is_admitted = (GNUNET_YES == is_admitted) ? GNUNET_YES : GNUNET_NO; 1310 dcsn->is_admitted = htonl (is_admitted);
1291 dcsn->slave_key = jh->slave_key; 1311 dcsn->slave_key = jh->slave_key;
1292 1312
1293 /* FIXME: add message parts to pmsg */ 1313 if (0 < join_resp_size)
1294 if (0 < pmsg_size) 1314 memcpy (&dcsn[1], join_resp, join_resp_size);
1295 memcpy (&dcsn[1], pmsg, pmsg_size);
1296 1315
1297 GNUNET_CONTAINER_DLL_insert_tail (ch->tmit_head, ch->tmit_tail, mq); 1316 GNUNET_CONTAINER_DLL_insert_tail (ch->tmit_head, ch->tmit_tail, mq);
1298 transmit_next (ch); 1317 transmit_next (ch);
1318 return GNUNET_OK;
1299} 1319}
1300 1320
1301 1321
@@ -1359,24 +1379,27 @@ GNUNET_PSYC_master_transmit_cancel (struct GNUNET_PSYC_MasterTransmitHandle *th)
1359 * notification on failure (as the channel may simply take days to approve, 1379 * notification on failure (as the channel may simply take days to approve,
1360 * and disapproval is simply being ignored). 1380 * and disapproval is simply being ignored).
1361 * 1381 *
1362 * @param cfg Configuration to use. 1382 * @param cfg Configuration to use.
1363 * @param channel_key ECC public key that identifies the channel we wish to join. 1383 * @param channel_key ECC public key that identifies the channel we wish to join.
1364 * @param slave_key ECC private-public key pair that identifies the slave, and 1384 * @param slave_key ECC private-public key pair that identifies the slave, and
1365 * used by multicast to sign the join request and subsequent unicast 1385 * used by multicast to sign the join request and subsequent unicast
1366 * requests sent to the master. 1386 * requests sent to the master.
1367 * @param origin Peer identity of the origin. 1387 * @param origin Peer identity of the origin.
1368 * @param relay_count Number of peers in the @a relays array. 1388 * @param relay_count Number of peers in the @a relays array.
1369 * @param relays Peer identities of members of the multicast group, which serve 1389 * @param relays Peer identities of members of the multicast group, which serve
1370 * as relays and used to join the group at. 1390 * as relays and used to join the group at.
1371 * @param message_cb Function to invoke on message parts received from the 1391 * @param message_cb Function to invoke on message parts received from the
1372 * channel, typically at least contains method handlers for @e join and 1392 * channel, typically at least contains method handlers for @e join and
1373 * @e part. 1393 * @e part.
1374 * @param slave_joined_cb Function invoked once we have joined the channel. 1394 * @param slave_connect_cb Function invoked once we have connected to the
1375 * @param cls Closure for @a message_cb and @a slave_joined_cb. 1395 * PSYC service.
1376 * @param method_name Method name for the join request. 1396 * @param join_decision_cb Function invoked once we have received a join
1377 * @param env Environment containing transient variables for the request, or NULL. 1397 * decision.
1378 * @param data Payload for the join message. 1398 * @param cls Closure for @a message_cb and @a slave_joined_cb.
1379 * @param data_size Number of bytes in @a data. 1399 * @param method_name Method name for the join request.
1400 * @param env Environment containing transient variables for the request, or NULL.
1401 * @param data Payload for the join message.
1402 * @param data_size Number of bytes in @a data.
1380 * 1403 *
1381 * @return Handle for the slave, NULL on error. 1404 * @return Handle for the slave, NULL on error.
1382 */ 1405 */
@@ -1388,7 +1411,8 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
1388 uint32_t relay_count, 1411 uint32_t relay_count,
1389 const struct GNUNET_PeerIdentity *relays, 1412 const struct GNUNET_PeerIdentity *relays,
1390 GNUNET_PSYC_MessageCallback message_cb, 1413 GNUNET_PSYC_MessageCallback message_cb,
1391 GNUNET_PSYC_SlaveJoinCallback slave_joined_cb, 1414 GNUNET_PSYC_SlaveConnectCallback connect_cb,
1415 GNUNET_PSYC_JoinDecisionCallback join_decision_cb,
1392 void *cls, 1416 void *cls,
1393 const char *method_name, 1417 const char *method_name,
1394 const struct GNUNET_ENV_Environment *env, 1418 const struct GNUNET_ENV_Environment *env,
@@ -1408,7 +1432,8 @@ GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
1408 req->relay_count = htonl (relay_count); 1432 req->relay_count = htonl (relay_count);
1409 memcpy (&req[1], relays, relay_count * sizeof (*relays)); 1433 memcpy (&req[1], relays, relay_count * sizeof (*relays));
1410 1434
1411 slv->join_cb = slave_joined_cb; 1435 slv->connect_cb = connect_cb;
1436 slv->join_dcsn_cb = join_decision_cb;
1412 ch->message_cb = message_cb; 1437 ch->message_cb = message_cb;
1413 ch->cb_cls = cls; 1438 ch->cb_cls = cls;
1414 1439
diff --git a/src/psyc/test_psyc.c b/src/psyc/test_psyc.c
index 4195e464b..8b4aad773 100644
--- a/src/psyc/test_psyc.c
+++ b/src/psyc/test_psyc.c
@@ -35,9 +35,9 @@
35#include "gnunet_env_lib.h" 35#include "gnunet_env_lib.h"
36#include "gnunet_psyc_service.h" 36#include "gnunet_psyc_service.h"
37 37
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
39 39
40#define DEBUG_SERVICE 0 40#define DEBUG_SERVICE 1
41 41
42 42
43/** 43/**
@@ -79,6 +79,7 @@ struct TransmitClosure
79 79
80struct TransmitClosure *tmit; 80struct TransmitClosure *tmit;
81 81
82static int join_req_count;
82 83
83enum 84enum
84{ 85{
@@ -167,8 +168,8 @@ end ()
167 168
168 169
169static void 170static void
170master_message (void *cls, uint64_t message_id, uint32_t flags, 171master_message_cb (void *cls, uint64_t message_id, uint32_t flags,
171 const struct GNUNET_MessageHeader *msg) 172 const struct GNUNET_MessageHeader *msg)
172{ 173{
173 if (NULL == msg) 174 if (NULL == msg)
174 { 175 {
@@ -211,8 +212,8 @@ master_message (void *cls, uint64_t message_id, uint32_t flags,
211 212
212 213
213static void 214static void
214slave_message (void *cls, uint64_t message_id, uint32_t flags, 215slave_message_cb (void *cls, uint64_t message_id, uint32_t flags,
215 const struct GNUNET_MessageHeader *msg) 216 const struct GNUNET_MessageHeader *msg)
216{ 217{
217 if (NULL == msg) 218 if (NULL == msg)
218 { 219 {
@@ -243,23 +244,6 @@ slave_message (void *cls, uint64_t message_id, uint32_t flags,
243 244
244 245
245static void 246static void
246join_request (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
247 const struct GNUNET_PSYC_MessageHeader *msg,
248 struct GNUNET_PSYC_JoinHandle *jh)
249{
250 struct GNUNET_HashCode slave_key_hash;
251 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
252 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
253 "Got join request from %s.\n",
254 GNUNET_h2s (&slave_key_hash));
255
256 GNUNET_PSYC_join_decision (jh, GNUNET_YES, 0, NULL, "_notice_join", NULL,
257 "you're in", 9);
258 // FIXME: also test refusing entry
259}
260
261
262static void
263transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 247transmit_resume (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
264{ 248{
265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n"); 249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n");
@@ -392,9 +376,23 @@ tmit_notify_data (void *cls, uint16_t *data_size, void *data)
392 376
393 377
394static void 378static void
395slave_joined (void *cls, uint64_t max_message_id) 379slave_join ();
380
381
382static void
383join_decision_cb (void *cls, int is_admitted,
384 const struct GNUNET_PSYC_MessageHeader *join_msg)
396{ 385{
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave joined: %lu\n", max_message_id); 386 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
387 "Slave got join decision: %d\n", is_admitted);
388
389 if (GNUNET_YES != is_admitted)
390 { /* First join request is refused, retry. */
391 //GNUNET_assert (1 == join_req_count);
392 slave_join ();
393 return;
394 }
395
398 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave sending request to master.\n"); 396 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Slave sending request to master.\n");
399 397
400 test = TEST_SLAVE_TRANSMIT; 398 test = TEST_SLAVE_TRANSMIT;
@@ -414,20 +412,46 @@ slave_joined (void *cls, uint64_t max_message_id)
414 GNUNET_PSYC_SLAVE_TRANSMIT_NONE); 412 GNUNET_PSYC_SLAVE_TRANSMIT_NONE);
415} 413}
416 414
415
416static void
417join_request_cb (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *slave_key,
418 const struct GNUNET_PSYC_MessageHeader *msg,
419 struct GNUNET_PSYC_JoinHandle *jh)
420{
421 struct GNUNET_HashCode slave_key_hash;
422 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
423 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
424 "Got join request from %s.\n",
425 GNUNET_h2s (&slave_key_hash));
426
427 /* Reject first request */
428 int is_admitted = (0 < join_req_count++) ? GNUNET_YES : GNUNET_NO;
429 GNUNET_PSYC_join_decision (jh, is_admitted, 0, NULL, NULL);
430}
431
432
433static void
434slave_connect_cb (void *cls, uint64_t max_message_id)
435{
436 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
437 "Slave connected: %lu\n", max_message_id);
438}
439
440
417static void 441static void
418slave_join () 442slave_join ()
419{ 443{
420 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Joining slave.\n"); 444 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Joining slave.\n");
421 445
422 struct GNUNET_PeerIdentity origin; 446 struct GNUNET_PeerIdentity origin; // FIXME: this peer
423 struct GNUNET_PeerIdentity relays[16];
424 struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create (); 447 struct GNUNET_ENV_Environment *env = GNUNET_ENV_environment_create ();
425 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, 448 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
426 "_foo", "bar baz", 7); 449 "_foo", "bar baz", 7);
427 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN, 450 GNUNET_ENV_environment_add (env, GNUNET_ENV_OP_ASSIGN,
428 "_foo_bar", "foo bar baz", 11); 451 "_foo_bar", "foo bar baz", 11);
429 slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin, 452 slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key, &origin,
430 16, relays, &slave_message, &slave_joined, NULL, 453 0, NULL, &slave_message_cb,
454 &slave_connect_cb, &join_decision_cb, NULL,
431 "_request_join", env, "some data", 9); 455 "_request_join", env, "some data", 9);
432 GNUNET_ENV_environment_destroy (env); 456 GNUNET_ENV_environment_destroy (env);
433} 457}
@@ -485,7 +509,7 @@ master_transmit ()
485 509
486 510
487static void 511static void
488master_started (void *cls, uint64_t max_message_id) 512master_start_cb (void *cls, uint64_t max_message_id)
489{ 513{
490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
491 "Master started: %" PRIu64 "\n", max_message_id); 515 "Master started: %" PRIu64 "\n", max_message_id);
@@ -521,8 +545,8 @@ run (void *cls,
521 545
522 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n"); 546 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Starting master.\n");
523 mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE, 547 mst = GNUNET_PSYC_master_start (cfg, channel_key, GNUNET_PSYC_CHANNEL_PRIVATE,
524 &master_message, &join_request, 548 &master_start_cb, &join_request_cb,
525 &master_started, NULL); 549 &master_message_cb, NULL);
526} 550}
527 551
528 552