aboutsummaryrefslogtreecommitdiff
path: root/src/psyc
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/psyc
parentc3bc1d8ef6e78e543d0077a57b04ae480f1d7caf (diff)
downloadgnunet-a7100389deab562e67d22ff68961b68a62341aec.tar.gz
gnunet-a7100389deab562e67d22ff68961b68a62341aec.zip
psyc, multicast: join decision
Diffstat (limited to 'src/psyc')
-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
5 files changed, 207 insertions, 59 deletions
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