aboutsummaryrefslogtreecommitdiff
path: root/src/social/gnunet-service-social.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/social/gnunet-service-social.c')
-rw-r--r--src/social/gnunet-service-social.c774
1 files changed, 407 insertions, 367 deletions
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c
index dee68fdb8..5b2a8ba9b 100644
--- a/src/social/gnunet-service-social.c
+++ b/src/social/gnunet-service-social.c
@@ -96,7 +96,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *apps_places;
96 * Application subscriptions per place. 96 * Application subscriptions per place.
97 * H(place_pub_key) -> H(app_id) 97 * H(place_pub_key) -> H(app_id)
98 */ 98 */
99static struct GNUNET_CONTAINER_MultiHashMap *places_apps; 99//static struct GNUNET_CONTAINER_MultiHashMap *places_apps;
100 100
101/** 101/**
102 * Connected applications. 102 * Connected applications.
@@ -255,10 +255,10 @@ struct Place
255 uint8_t is_ready; 255 uint8_t is_ready;
256 256
257 /** 257 /**
258 * Is the client disconnected? 258 * Is the client disconnecting?
259 * #GNUNET_YES or #GNUNET_NO 259 * #GNUNET_YES or #GNUNET_NO
260 */ 260 */
261 uint8_t is_disconnected; 261 uint8_t is_disconnecting;
262 262
263 /** 263 /**
264 * Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)? 264 * Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)?
@@ -348,7 +348,7 @@ struct Guest
348 /** 348 /**
349 * Join request to be transmitted to the master on join. 349 * Join request to be transmitted to the master on join.
350 */ 350 */
351 struct GNUNET_MessageHeader *join_req; 351 struct GNUNET_MessageHeader *join_req; // FIXME: not used!
352 352
353 /** 353 /**
354 * Join decision received from PSYC. 354 * Join decision received from PSYC.
@@ -487,8 +487,6 @@ cleanup_host (struct Host *hst)
487{ 487{
488 struct Place *plc = &hst->place; 488 struct Place *plc = &hst->place;
489 489
490 if (NULL != hst->master)
491 GNUNET_PSYC_master_stop (hst->master, GNUNET_NO, NULL, NULL); // FIXME
492 GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs); 490 GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs);
493 GNUNET_CONTAINER_multihashmap_destroy (hst->relay_msgs); 491 GNUNET_CONTAINER_multihashmap_destroy (hst->relay_msgs);
494 GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc); 492 GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc);
@@ -505,7 +503,7 @@ cleanup_guest (struct Guest *gst)
505 struct GNUNET_CONTAINER_MultiHashMap * 503 struct GNUNET_CONTAINER_MultiHashMap *
506 plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, 504 plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests,
507 &plc->pub_key_hash); 505 &plc->pub_key_hash);
508 GNUNET_assert (NULL != plc_gst); // FIXME 506 GNUNET_assert (NULL != plc_gst);
509 GNUNET_CONTAINER_multihashmap_remove (plc_gst, &plc->ego_pub_hash, gst); 507 GNUNET_CONTAINER_multihashmap_remove (plc_gst, &plc->ego_pub_hash, gst);
510 508
511 if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst)) 509 if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst))
@@ -520,8 +518,6 @@ cleanup_guest (struct Guest *gst)
520 GNUNET_free (gst->join_req); 518 GNUNET_free (gst->join_req);
521 if (NULL != gst->relays) 519 if (NULL != gst->relays)
522 GNUNET_free (gst->relays); 520 GNUNET_free (gst->relays);
523 if (NULL != gst->slave)
524 GNUNET_PSYC_slave_part (gst->slave, GNUNET_NO, NULL, NULL); // FIXME
525 GNUNET_CONTAINER_multihashmap_remove (guests, &plc->pub_key_hash, plc); 521 GNUNET_CONTAINER_multihashmap_remove (guests, &plc->pub_key_hash, plc);
526} 522}
527 523
@@ -537,8 +533,8 @@ cleanup_place (void *cls)
537 struct Place *plc = cls; 533 struct Place *plc = cls;
538 534
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
540 "%p Cleaning up place %s\n", 536 "cleaning up place %s\n",
541 plc, GNUNET_h2s (&plc->pub_key_hash)); 537 GNUNET_h2s (&plc->pub_key_hash));
542 538
543 (GNUNET_YES == plc->is_host) 539 (GNUNET_YES == plc->is_host)
544 ? cleanup_host ((struct Host *) plc) 540 ? cleanup_host ((struct Host *) plc)
@@ -583,12 +579,19 @@ client_notify_disconnect (void *cls,
583 { 579 {
584 if (cli->client == client) 580 if (cli->client == client)
585 { 581 {
586 GNUNET_CONTAINER_DLL_remove (plc->clients_head, plc->clients_tail, cli); 582 GNUNET_CONTAINER_DLL_remove (plc->clients_head,
583 plc->clients_tail,
584 cli);
587 GNUNET_free (cli); 585 GNUNET_free (cli);
588 break; 586 break;
589 } 587 }
590 cli = cli->next; 588 cli = cli->next;
591 } 589 }
590 if (GNUNET_YES == plc->is_disconnecting)
591 {
592 GNUNET_PSYC_slicer_destroy (plc->slicer);
593 GNUNET_free (plc);
594 }
592} 595}
593 596
594 597
@@ -605,46 +608,55 @@ client_notify_connect (void *cls,
605 struct GNUNET_SERVICE_Client *client, 608 struct GNUNET_SERVICE_Client *client,
606 struct GNUNET_MQ_Handle *mq) 609 struct GNUNET_MQ_Handle *mq)
607{ 610{
608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client); 611 struct Client *c = GNUNET_new (struct Client);
609 612
610 struct Client *c = GNUNET_malloc (sizeof (*c)); 613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
614 "Client %p connected with queue %p\n",
615 client,
616 mq);
611 c->client = client; 617 c->client = client;
612
613 return c; 618 return c;
614} 619}
615 620
616 621
617/** 622/**
618 * Send message to a client. 623 * Send message to all clients connected to a place and
619 */ 624 * takes care of freeing @env.
620static inline void
621client_send_msg (struct GNUNET_SERVICE_Client *client,
622 const struct GNUNET_MessageHeader *msg)
623{
624 struct GNUNET_MQ_Envelope *
625 env = GNUNET_MQ_msg_copy (msg);
626
627 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
628 env);
629}
630
631
632/**
633 * Send message to all clients connected to a place.
634 */ 625 */
635static void 626static void
636place_send_msg (const struct Place *plc, 627place_send_msg (const struct Place *plc,
637 const struct GNUNET_MessageHeader *msg) 628 struct GNUNET_MQ_Envelope *env)
638{ 629{
630 struct ClientListItem *cli = plc->clients_head;
631
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
640 "%p Sending message to clients of place.\n", plc); 633 "%p Sending message to clients of place.\n", plc);
641
642 struct ClientListItem *cli = plc->clients_head;
643 while (NULL != cli) 634 while (NULL != cli)
644 { 635 {
645 client_send_msg (cli->client, msg); 636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
637 "Sending message to client %p\n",
638 cli);
639 GNUNET_MQ_send_copy (GNUNET_SERVICE_client_get_mq (cli->client),
640 env);
646 cli = cli->next; 641 cli = cli->next;
647 } 642 }
643 GNUNET_MQ_discard (env);
644}
645
646
647static void
648place_send_leave_ack (struct Place *plc)
649{
650 struct GNUNET_MQ_Envelope *env;
651
652 for (struct ClientListItem *cli = plc->clients_head;
653 NULL != cli;
654 cli = cli->next)
655 {
656 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK);
657 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cli->client),
658 env);
659 }
648} 660}
649 661
650 662
@@ -666,23 +678,21 @@ static void
666client_send_result (struct GNUNET_SERVICE_Client *client, uint64_t op_id, 678client_send_result (struct GNUNET_SERVICE_Client *client, uint64_t op_id,
667 int64_t result_code, const void *data, uint16_t data_size) 679 int64_t result_code, const void *data, uint16_t data_size)
668{ 680{
681 struct GNUNET_MQ_Envelope *env;
669 struct GNUNET_OperationResultMessage *res; 682 struct GNUNET_OperationResultMessage *res;
670 683
671 res = GNUNET_malloc (sizeof (*res) + data_size); 684 env = GNUNET_MQ_msg_extra (res,
672 res->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE); 685 data_size,
673 res->header.size = htons (sizeof (*res) + data_size); 686 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE);
674 res->result_code = GNUNET_htonll (result_code); 687 res->result_code = GNUNET_htonll (result_code);
675 res->op_id = op_id; 688 res->op_id = op_id;
676 if (0 < data_size) 689 if (0 < data_size)
677 GNUNET_memcpy (&res[1], data, data_size); 690 GNUNET_memcpy (&res[1], data, data_size);
678
679 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
680 "%p Sending result to client for operation #%" PRIu64 ": " 692 "%p Sending result to client for operation #%" PRIu64 ": "
681 "%" PRId64 " (size: %u)\n", 693 "%" PRId64 " (size: %u)\n",
682 client, GNUNET_ntohll (op_id), result_code, data_size); 694 client, GNUNET_ntohll (op_id), result_code, data_size);
683 695 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
684 client_send_msg (client, &res->header);
685 GNUNET_free (res);
686} 696}
687 697
688 698
@@ -690,19 +700,21 @@ static void
690client_send_host_enter_ack (struct GNUNET_SERVICE_Client *client, 700client_send_host_enter_ack (struct GNUNET_SERVICE_Client *client,
691 struct Host *hst, uint32_t result) 701 struct Host *hst, uint32_t result)
692{ 702{
703 struct GNUNET_MQ_Envelope *env;
704 struct HostEnterAck *hack;
693 struct Place *plc = &hst->place; 705 struct Place *plc = &hst->place;
694 706
695 struct HostEnterAck hack; 707 env = GNUNET_MQ_msg (hack,
696 hack.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); 708 GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK);
697 hack.header.size = htons (sizeof (hack)); 709 hack->result_code = htonl (result);
698 hack.result_code = htonl (result); 710 hack->max_message_id = GNUNET_htonll (plc->max_message_id);
699 hack.max_message_id = GNUNET_htonll (plc->max_message_id); 711 hack->place_pub_key = plc->pub_key;
700 hack.place_pub_key = plc->pub_key;
701 712
702 if (NULL != client) 713 if (NULL != client)
703 client_send_msg (client, &hack.header); 714 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
715 env);
704 else 716 else
705 place_send_msg (plc, &hack.header); 717 place_send_msg (plc, env);
706} 718}
707 719
708 720
@@ -736,7 +748,8 @@ psyc_recv_join_request (void *cls,
736 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash); 748 GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
737 GNUNET_CONTAINER_multihashmap_put (hst->join_reqs, &slave_key_hash, jh, 749 GNUNET_CONTAINER_multihashmap_put (hst->join_reqs, &slave_key_hash, jh,
738 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 750 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
739 place_send_msg (&hst->place, &req->header); 751 place_send_msg (&hst->place,
752 GNUNET_MQ_msg_copy (&req->header));
740} 753}
741 754
742 755
@@ -746,18 +759,29 @@ psyc_recv_join_request (void *cls,
746static void 759static void
747psyc_slave_connected (void *cls, int result, uint64_t max_message_id) 760psyc_slave_connected (void *cls, int result, uint64_t max_message_id)
748{ 761{
762 struct GNUNET_PSYC_CountersResultMessage *res;
763 struct GNUNET_MQ_Envelope *env;
749 struct Guest *gst = cls; 764 struct Guest *gst = cls;
750 struct Place *plc = &gst->place; 765 struct Place *plc = &gst->place;
766
751 plc->max_message_id = max_message_id; 767 plc->max_message_id = max_message_id;
752 plc->is_ready = GNUNET_YES; 768 plc->is_ready = GNUNET_YES;
769 env = GNUNET_MQ_msg (res,
770 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
771 res->result_code =
772 (result != GNUNET_SYSERR) ? htonl (GNUNET_OK) : htonl (GNUNET_SYSERR);
773 res->max_message_id = GNUNET_htonll (plc->max_message_id);
774 place_send_msg (plc, env);
775}
753 776
754 struct GNUNET_PSYC_CountersResultMessage res;
755 res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
756 res.header.size = htons (sizeof (res));
757 res.result_code = htonl (result);
758 res.max_message_id = GNUNET_htonll (plc->max_message_id);
759 777
760 place_send_msg (plc, &res.header); 778static void
779slave_parted_after_join_decision (void *cls)
780{
781 struct Guest *gst = cls;
782
783 GNUNET_assert (NULL != gst->join_dcsn);
784 place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&gst->join_dcsn->header));
761} 785}
762 786
763 787
@@ -771,7 +795,21 @@ psyc_recv_join_dcsn (void *cls,
771 const struct GNUNET_PSYC_Message *join_msg) 795 const struct GNUNET_PSYC_Message *join_msg)
772{ 796{
773 struct Guest *gst = cls; 797 struct Guest *gst = cls;
774 place_send_msg (&gst->place, &dcsn->header); 798
799 gst->join_dcsn = GNUNET_malloc (dcsn->header.size);
800 GNUNET_memcpy (gst->join_dcsn,
801 dcsn,
802 dcsn->header.size);
803 if (GNUNET_NO == is_admitted)
804 {
805 GNUNET_PSYC_slave_part (gst->slave,
806 GNUNET_NO,
807 &slave_parted_after_join_decision,
808 gst);
809 gst->slave = NULL;
810 return;
811 }
812 place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&gst->join_dcsn->header));
775} 813}
776 814
777 815
@@ -792,7 +830,7 @@ psyc_recv_message (void *cls,
792 830
793 GNUNET_PSYC_slicer_message (plc->slicer, msg); 831 GNUNET_PSYC_slicer_message (plc->slicer, msg);
794 832
795 place_send_msg (plc, &msg->header); 833 place_send_msg (plc, GNUNET_MQ_msg_copy (&msg->header));
796} 834}
797 835
798 836
@@ -1096,9 +1134,6 @@ place_init (struct Place *plc)
1096static int 1134static int
1097place_add (const struct PlaceEnterRequest *ereq) 1135place_add (const struct PlaceEnterRequest *ereq)
1098{ 1136{
1099 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1100 "Adding place to hashmap:\n");
1101
1102 struct EgoPlacePublicKey ego_place_pub_key = { 1137 struct EgoPlacePublicKey ego_place_pub_key = {
1103 .ego_pub_key = ereq->ego_pub_key, 1138 .ego_pub_key = ereq->ego_pub_key,
1104 .place_pub_key = ereq->place_pub_key, 1139 .place_pub_key = ereq->place_pub_key,
@@ -1173,7 +1208,9 @@ app_place_add (const char *app_id,
1173 return GNUNET_NO; 1208 return GNUNET_NO;
1174 1209
1175 if (GNUNET_SYSERR == place_add (ereq)) 1210 if (GNUNET_SYSERR == place_add (ereq))
1211 {
1176 return GNUNET_SYSERR; 1212 return GNUNET_SYSERR;
1213 }
1177 1214
1178 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (app_places, &ego_place_pub_hash, NULL, 1215 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (app_places, &ego_place_pub_hash, NULL,
1179 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 1216 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
@@ -1181,32 +1218,6 @@ app_place_add (const char *app_id,
1181 GNUNET_break (0); 1218 GNUNET_break (0);
1182 return GNUNET_SYSERR; 1219 return GNUNET_SYSERR;
1183 } 1220 }
1184
1185 struct GNUNET_HashCode place_pub_hash;
1186 GNUNET_CRYPTO_hash (&ereq->place_pub_key, sizeof (ereq->place_pub_key), &place_pub_hash);
1187
1188 struct GNUNET_CONTAINER_MultiHashMap *
1189 place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, &place_pub_hash);
1190 if (NULL == place_apps)
1191 {
1192 place_apps = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
1193 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (places_apps, &place_pub_hash, place_apps,
1194 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1195 {
1196 GNUNET_break (0);
1197 }
1198 }
1199
1200 size_t app_id_size = strlen (app_id) + 1;
1201 void *app_id_value = GNUNET_malloc (app_id_size);
1202 GNUNET_memcpy (app_id_value, app_id, app_id_size);
1203
1204 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (place_apps, &app_id_hash, app_id_value,
1205 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1206 {
1207 GNUNET_break (0);
1208 }
1209
1210 return GNUNET_OK; 1221 return GNUNET_OK;
1211} 1222}
1212 1223
@@ -1223,7 +1234,10 @@ static int
1223app_place_save (const char *app_id, 1234app_place_save (const char *app_id,
1224 const struct PlaceEnterRequest *ereq) 1235 const struct PlaceEnterRequest *ereq)
1225{ 1236{
1226 app_place_add (app_id, ereq); 1237 if (GNUNET_SYSERR == app_place_add (app_id, ereq))
1238 {
1239 GNUNET_assert (0);
1240 }
1227 1241
1228 if (NULL == dir_places) 1242 if (NULL == dir_places)
1229 return GNUNET_SYSERR; 1243 return GNUNET_SYSERR;
@@ -1304,18 +1318,6 @@ app_place_remove (const char *app_id,
1304 if (NULL != app_places) 1318 if (NULL != app_places)
1305 GNUNET_CONTAINER_multihashmap_remove (app_places, &place_pub_hash, NULL); 1319 GNUNET_CONTAINER_multihashmap_remove (app_places, &place_pub_hash, NULL);
1306 1320
1307 struct GNUNET_CONTAINER_MultiHashMap *
1308 place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, &place_pub_hash);
1309 if (NULL != place_apps)
1310 {
1311 void *app_id_value = GNUNET_CONTAINER_multihashmap_get (place_apps, &app_id_hash);
1312 if (NULL != app_id_value)
1313 {
1314 GNUNET_CONTAINER_multihashmap_remove (place_apps, &app_id_hash, app_id_value);
1315 GNUNET_free (app_id_value);
1316 }
1317 }
1318
1319 int ret = GNUNET_OK; 1321 int ret = GNUNET_OK;
1320 1322
1321 if (0 != unlink (app_place_filename)) 1323 if (0 != unlink (app_place_filename))
@@ -1407,6 +1409,124 @@ msg_proc_parse (const struct MsgProcRequest *mpreq,
1407} 1409}
1408 1410
1409 1411
1412void
1413app_notify_place (const struct GNUNET_MessageHeader *msg,
1414 struct GNUNET_SERVICE_Client *client)
1415{
1416 struct AppPlaceMessage *amsg;
1417 struct GNUNET_MQ_Envelope *env;
1418 uint16_t msg_size = ntohs (msg->size);
1419
1420 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1421 "%p Sending place notification of type %u to client.\n",
1422 client, ntohs (msg->type));
1423 switch (ntohs (msg->type))
1424 {
1425 case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER:
1426 {
1427 struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg;
1428 if (msg_size < sizeof (struct HostEnterRequest))
1429 return;
1430 env = GNUNET_MQ_msg (amsg,
1431 GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE);
1432 // FIXME: also notify about not entered places
1433 amsg->place_state = GNUNET_SOCIAL_PLACE_STATE_ENTERED;
1434 amsg->is_host = GNUNET_YES;
1435 amsg->ego_pub_key = hreq->ego_pub_key;
1436 amsg->place_pub_key = hreq->place_pub_key;
1437 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1438 env);
1439 break;
1440 }
1441 case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER:
1442 {
1443 if (msg_size < sizeof (struct GuestEnterRequest))
1444 return;
1445 struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg;
1446 env = GNUNET_MQ_msg (amsg,
1447 GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE);
1448 // FIXME: also notify about not entered places
1449 amsg->place_state = GNUNET_SOCIAL_PLACE_STATE_ENTERED;
1450 amsg->is_host = GNUNET_NO;
1451 amsg->ego_pub_key = greq->ego_pub_key;
1452 amsg->place_pub_key = greq->place_pub_key;
1453 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1454 env);
1455 break;
1456 }
1457 default:
1458 return;
1459 }
1460}
1461
1462
1463void
1464app_notify_place_end (struct GNUNET_SERVICE_Client *client)
1465{
1466 struct GNUNET_MQ_Envelope *env;
1467
1468 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1469 "%p Sending end of place list notification to client\n",
1470 client);
1471 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END);
1472 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1473 env);
1474}
1475
1476
1477void
1478app_notify_ego (struct Ego *ego, struct GNUNET_SERVICE_Client *client)
1479{
1480 struct AppEgoMessage *emsg;
1481 struct GNUNET_MQ_Envelope *env;
1482 size_t name_size = strlen (ego->name) + 1;
1483
1484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1485 "%p Sending ego notification to client: %s\n",
1486 client, ego->name);
1487 env = GNUNET_MQ_msg_extra (emsg,
1488 name_size,
1489 GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO);
1490 GNUNET_CRYPTO_ecdsa_key_get_public (&ego->key, &emsg->ego_pub_key);
1491 GNUNET_memcpy (&emsg[1], ego->name, name_size);
1492 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1493 env);
1494}
1495
1496
1497void
1498app_notify_ego_end (struct GNUNET_SERVICE_Client *client)
1499{
1500 struct GNUNET_MQ_Envelope *env;
1501
1502 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1503 "%p Sending end of ego list notification to client\n",
1504 client);
1505 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END);
1506 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1507 env);
1508}
1509
1510
1511int
1512app_place_entry_notify (void *cls, const struct GNUNET_HashCode *key, void *value)
1513{
1514 struct GNUNET_MessageHeader *
1515 msg = GNUNET_CONTAINER_multihashmap_get (places, key);
1516 if (NULL != msg)
1517 app_notify_place (msg, cls);
1518 return GNUNET_YES;
1519}
1520
1521
1522int
1523ego_entry (void *cls, const struct GNUNET_HashCode *key, void *value)
1524{
1525 app_notify_ego (value, cls);
1526 return GNUNET_YES;
1527}
1528
1529
1410static int 1530static int
1411check_client_msg_proc_set (void *cls, 1531check_client_msg_proc_set (void *cls,
1412 const struct MsgProcRequest *mpreq) 1532 const struct MsgProcRequest *mpreq)
@@ -1518,9 +1638,8 @@ static void
1518handle_client_host_enter (void *cls, 1638handle_client_host_enter (void *cls,
1519 const struct HostEnterRequest *hr) 1639 const struct HostEnterRequest *hr)
1520{ 1640{
1521 struct Client *c = cls; 1641 struct Client *c = cls;
1522 struct GNUNET_SERVICE_Client *client = c->client; 1642 struct GNUNET_SERVICE_Client *client = c->client;
1523
1524 struct HostEnterRequest * 1643 struct HostEnterRequest *
1525 hreq = (struct HostEnterRequest *) GNUNET_copy_message (&hr->header); 1644 hreq = (struct HostEnterRequest *) GNUNET_copy_message (&hr->header);
1526 1645
@@ -1578,7 +1697,7 @@ handle_client_host_enter (void *cls,
1578 if (ret != GNUNET_SYSERR) 1697 if (ret != GNUNET_SYSERR)
1579 { 1698 {
1580 1699
1581 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1700 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1582 "%p Client connected as host to place %s.\n", 1701 "%p Client connected as host to place %s.\n",
1583 hst, GNUNET_h2s (&plc->pub_key_hash)); 1702 hst, GNUNET_h2s (&plc->pub_key_hash));
1584 1703
@@ -1586,6 +1705,7 @@ handle_client_host_enter (void *cls,
1586 cli->client = client; 1705 cli->client = client;
1587 GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli); 1706 GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli);
1588 c->place = plc; 1707 c->place = plc;
1708 app_notify_place (&hreq->header, client);
1589 } 1709 }
1590 1710
1591 GNUNET_CRYPTO_eddsa_key_clear (&hreq->place_key); 1711 GNUNET_CRYPTO_eddsa_key_clear (&hreq->place_key);
@@ -1622,8 +1742,12 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
1622 struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash); 1742 struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash);
1623 1743
1624 if (NULL == ego) 1744 if (NULL == ego)
1745 {
1625 return GNUNET_SYSERR; 1746 return GNUNET_SYSERR;
1747 }
1626 1748
1749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1750 "entering as guest\n");
1627 struct GNUNET_HashCode place_pub_hash; 1751 struct GNUNET_HashCode place_pub_hash;
1628 GNUNET_CRYPTO_hash (&greq->place_pub_key, sizeof (greq->place_pub_key), 1752 GNUNET_CRYPTO_hash (&greq->place_pub_key, sizeof (greq->place_pub_key),
1629 &place_pub_hash); 1753 &place_pub_hash);
@@ -1635,9 +1759,16 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
1635 if (NULL != plc_gst) 1759 if (NULL != plc_gst)
1636 gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &ego_pub_hash); 1760 gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &ego_pub_hash);
1637 1761
1638 if (NULL == gst || NULL == gst->slave) 1762 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1763 "plc_gst = %p, gst = %p\n",
1764 plc_gst,
1765 gst);
1766 if (NULL == gst)
1639 { 1767 {
1640 gst = GNUNET_new (struct Guest); 1768 gst = GNUNET_new (struct Guest);
1769 }
1770 if (NULL == gst->slave)
1771 {
1641 gst->origin = greq->origin; 1772 gst->origin = greq->origin;
1642 gst->relay_count = ntohl (greq->relay_count); 1773 gst->relay_count = ntohl (greq->relay_count);
1643 1774
@@ -1710,11 +1841,12 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
1710 plc_gst = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 1841 plc_gst = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1711 (void) GNUNET_CONTAINER_multihashmap_put (place_guests, &plc->pub_key_hash, plc_gst, 1842 (void) GNUNET_CONTAINER_multihashmap_put (place_guests, &plc->pub_key_hash, plc_gst,
1712 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1843 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1713 } 1844 (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash, gst,
1714 (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash, gst, 1845 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1715 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1846 (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst,
1716 (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst,
1717 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1847 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1848
1849 }
1718 gst->slave 1850 gst->slave
1719 = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &plc->ego_key, 1851 = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &plc->ego_key,
1720 gst->join_flags, &gst->origin, 1852 gst->join_flags, &gst->origin,
@@ -1724,6 +1856,9 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
1724 &psyc_recv_join_dcsn, 1856 &psyc_recv_join_dcsn,
1725 gst, join_msg); 1857 gst, join_msg);
1726 plc->channel = GNUNET_PSYC_slave_get_channel (gst->slave); 1858 plc->channel = GNUNET_PSYC_slave_get_channel (gst->slave);
1859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1860 "slave entered channel %p\n",
1861 plc->channel);
1727 ret = GNUNET_YES; 1862 ret = GNUNET_YES;
1728 } 1863 }
1729 1864
@@ -1734,78 +1869,96 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
1734 1869
1735 1870
1736static int 1871static int
1737check_client_guest_enter (void *cls, 1872client_guest_enter (struct Client *c,
1738 const struct GuestEnterRequest *greq) 1873 const struct GuestEnterRequest *greq)
1739{
1740 return GNUNET_OK;
1741}
1742
1743
1744/**
1745 * Handle a connecting client entering a place as guest.
1746 */
1747static void
1748handle_client_guest_enter (void *cls,
1749 const struct GuestEnterRequest *greq)
1750{ 1874{
1751 struct Client *c = cls; 1875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1876 "client_guest_enter\n");
1877 struct GNUNET_PSYC_CountersResultMessage *result_msg;
1878 struct GNUNET_MQ_Envelope *env;
1752 struct GNUNET_SERVICE_Client *client = c->client; 1879 struct GNUNET_SERVICE_Client *client = c->client;
1753
1754 uint16_t remaining = ntohs (greq->header.size) - sizeof (*greq); 1880 uint16_t remaining = ntohs (greq->header.size) - sizeof (*greq);
1755 const char *app_id = NULL; 1881 const char *app_id = NULL;
1756 uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &greq[1], 1882 uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &greq[1],
1757 remaining, 1, &app_id); 1883 remaining, 1, &app_id);
1758 if (0 == offset)
1759 {
1760 GNUNET_break (0);
1761 GNUNET_SERVICE_client_drop (client);
1762 return;
1763 }
1764
1765 struct Guest *gst = NULL; 1884 struct Guest *gst = NULL;
1766 struct Place *plc = NULL; 1885 struct Place *plc = NULL;
1767 1886
1887 if (0 == offset)
1888 {
1889 return GNUNET_SYSERR;
1890 }
1768 switch (guest_enter (greq, &gst)) 1891 switch (guest_enter (greq, &gst))
1769 { 1892 {
1770 case GNUNET_YES: 1893 case GNUNET_YES:
1894 {
1771 plc = c->place = &gst->place; 1895 plc = c->place = &gst->place;
1896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1897 "guest entered successfully to local place %s\n",
1898 GNUNET_h2s (&plc->pub_key_hash));
1772 plc->guest = gst; 1899 plc->guest = gst;
1773 app_place_save (app_id, (const struct PlaceEnterRequest *) greq); 1900 app_place_save (app_id, (const struct PlaceEnterRequest *) greq);
1901 app_notify_place (&greq->header, client);
1774 break; 1902 break;
1775 1903 }
1776 case GNUNET_NO: 1904 case GNUNET_NO:
1777 { 1905 {
1778 plc = c->place = &gst->place; 1906 plc = c->place = &gst->place;
1907 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1908 "guest re-entered successfully to local place %s\n",
1909 GNUNET_h2s (&plc->pub_key_hash));
1779 plc->guest = gst; 1910 plc->guest = gst;
1780 1911 env = GNUNET_MQ_msg (result_msg,
1781 struct GNUNET_PSYC_CountersResultMessage res; 1912 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
1782 res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK); 1913 result_msg->result_code = htonl (GNUNET_OK);
1783 res.header.size = htons (sizeof (res)); 1914 result_msg->max_message_id = GNUNET_htonll (plc->max_message_id);
1784 res.result_code = htonl (GNUNET_OK); 1915 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1785 res.max_message_id = GNUNET_htonll (plc->max_message_id); 1916 env);
1786
1787 client_send_msg (client, &res.header);
1788 if (NULL != gst->join_dcsn) 1917 if (NULL != gst->join_dcsn)
1789 client_send_msg (client, &gst->join_dcsn->header); 1918 {
1790 1919 env = GNUNET_MQ_msg_copy (&gst->join_dcsn->header);
1920 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
1921 env);
1922 }
1791 break; 1923 break;
1792 } 1924 }
1793 case GNUNET_SYSERR: 1925 case GNUNET_SYSERR:
1794 GNUNET_break (0); 1926 {
1795 GNUNET_SERVICE_client_drop (client); 1927 return GNUNET_SYSERR;
1796 return; 1928 }
1797 } 1929 }
1798
1799 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1800 "%p Client connected as guest to place %s.\n",
1801 gst, GNUNET_h2s (&plc->pub_key_hash));
1802 1930
1803 struct ClientListItem *cli = GNUNET_new (struct ClientListItem); 1931 struct ClientListItem *cli = GNUNET_new (struct ClientListItem);
1804 cli->client = client; 1932 cli->client = client;
1805 GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli); 1933 GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli);
1934 return GNUNET_OK;
1935}
1806 1936
1807 c->place = plc; 1937
1808 GNUNET_SERVICE_client_continue (client); 1938static int
1939check_client_guest_enter (void *cls,
1940 const struct GuestEnterRequest *greq)
1941{
1942 return GNUNET_OK;
1943}
1944
1945
1946/**
1947 * Handle a connecting client entering a place as guest.
1948 */
1949static void
1950handle_client_guest_enter (void *cls,
1951 const struct GuestEnterRequest *greq)
1952{
1953 struct Client *c = cls;
1954
1955 if (GNUNET_SYSERR == client_guest_enter (c, greq))
1956 {
1957 GNUNET_break (0);
1958 GNUNET_SERVICE_client_drop (c->client);
1959 return;
1960 }
1961 GNUNET_SERVICE_client_continue (c->client);
1809} 1962}
1810 1963
1811 1964
@@ -1830,7 +1983,7 @@ gns_result_guest_enter (void *cls, uint32_t rd_count,
1830{ 1983{
1831 struct GuestEnterByNameClosure *gcls = cls; 1984 struct GuestEnterByNameClosure *gcls = cls;
1832 struct Client *c = gcls->client; 1985 struct Client *c = gcls->client;
1833 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1834 "%p GNS result: %u records.\n", 1987 "%p GNS result: %u records.\n",
1835 c, rd_count); 1988 c, rd_count);
1836 1989
@@ -1882,7 +2035,7 @@ gns_result_guest_enter (void *cls, uint32_t rd_count,
1882 p += relay_size; 2035 p += relay_size;
1883 GNUNET_memcpy (p, gcls->join_msg, join_msg_size); 2036 GNUNET_memcpy (p, gcls->join_msg, join_msg_size);
1884 2037
1885 handle_client_guest_enter (c, greq); 2038 client_guest_enter (c, greq);
1886 2039
1887 GNUNET_free (gcls->app_id); 2040 GNUNET_free (gcls->app_id);
1888 if (NULL != gcls->password) 2041 if (NULL != gcls->password)
@@ -1960,118 +2113,7 @@ handle_client_guest_enter_by_name (void *cls,
1960 GNUNET_GNSRECORD_TYPE_PLACE, 2113 GNUNET_GNSRECORD_TYPE_PLACE,
1961 GNUNET_GNS_LO_DEFAULT, 2114 GNUNET_GNS_LO_DEFAULT,
1962 &gns_result_guest_enter, gcls); 2115 &gns_result_guest_enter, gcls);
1963} 2116 GNUNET_SERVICE_client_continue (client);
1964
1965
1966void
1967app_notify_place (struct GNUNET_MessageHeader *msg,
1968 struct GNUNET_SERVICE_Client *client)
1969{
1970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1971 "%p Sending place notification of type %u to client.\n",
1972 client, ntohs (msg->type));
1973
1974 uint16_t msg_size = ntohs (msg->size);
1975 struct AppPlaceMessage amsg;
1976 amsg.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE);
1977 amsg.header.size = htons (sizeof (amsg));
1978 // FIXME: also notify about not entered places
1979 amsg.place_state = GNUNET_SOCIAL_PLACE_STATE_ENTERED;
1980
1981 switch (ntohs (msg->type))
1982 {
1983 case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER:
1984 if (msg_size < sizeof (struct HostEnterRequest))
1985 return;
1986 struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg;
1987 amsg.is_host = GNUNET_YES;
1988 amsg.ego_pub_key = hreq->ego_pub_key;
1989 amsg.place_pub_key = hreq->place_pub_key;
1990 break;
1991
1992 case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER:
1993 if (msg_size < sizeof (struct GuestEnterRequest))
1994 return;
1995 struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg;
1996 amsg.is_host = GNUNET_NO;
1997 amsg.ego_pub_key = greq->ego_pub_key;
1998 amsg.place_pub_key = greq->place_pub_key;
1999 break;
2000
2001 default:
2002 return;
2003 }
2004
2005 client_send_msg (client, &amsg.header);
2006}
2007
2008
2009void
2010app_notify_place_end (struct GNUNET_SERVICE_Client *client)
2011{
2012 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2013 "%p Sending end of place list notification to client\n",
2014 client);
2015
2016 struct GNUNET_MessageHeader msg;
2017 msg.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END);
2018 msg.size = htons (sizeof (msg));
2019
2020 client_send_msg (client, &msg);
2021}
2022
2023
2024void
2025app_notify_ego (struct Ego *ego, struct GNUNET_SERVICE_Client *client)
2026{
2027 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2028 "%p Sending ego notification to client: %s\n",
2029 client, ego->name);
2030
2031 size_t name_size = strlen (ego->name) + 1;
2032 struct AppEgoMessage *emsg = GNUNET_malloc (sizeof (*emsg) + name_size);
2033 emsg->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO);
2034 emsg->header.size = htons (sizeof (*emsg) + name_size);
2035
2036 GNUNET_CRYPTO_ecdsa_key_get_public (&ego->key, &emsg->ego_pub_key);
2037 GNUNET_memcpy (&emsg[1], ego->name, name_size);
2038
2039 client_send_msg (client, &emsg->header);
2040 GNUNET_free (emsg);
2041}
2042
2043
2044void
2045app_notify_ego_end (struct GNUNET_SERVICE_Client *client)
2046{
2047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2048 "%p Sending end of ego list notification to client\n",
2049 client);
2050
2051 struct GNUNET_MessageHeader msg;
2052 msg.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END);
2053 msg.size = htons (sizeof (msg));
2054
2055 client_send_msg (client, &msg);
2056}
2057
2058
2059int
2060app_place_entry_notify (void *cls, const struct GNUNET_HashCode *key, void *value)
2061{
2062 struct GNUNET_MessageHeader *
2063 msg = GNUNET_CONTAINER_multihashmap_get (places, key);
2064 if (NULL != msg)
2065 app_notify_place (msg, cls);
2066 return GNUNET_YES;
2067}
2068
2069
2070int
2071ego_entry (void *cls, const struct GNUNET_HashCode *key, void *value)
2072{
2073 app_notify_ego (value, cls);
2074 return GNUNET_YES;
2075} 2117}
2076 2118
2077 2119
@@ -2154,13 +2196,15 @@ handle_client_app_detach (void *cls,
2154} 2196}
2155 2197
2156 2198
2157int 2199static void
2158app_places_entry_remove (void *cls, const struct GNUNET_HashCode *key, void *value) 2200place_leave_cb (void *cls)
2159{ 2201{
2160 struct Place *plc = cls; 2202 struct Place *plc = cls;
2161 const char *app_id = value; 2203
2162 app_place_remove (app_id, &plc->ego_pub_key, &plc->pub_key); 2204 place_send_leave_ack (plc);
2163 return GNUNET_YES; 2205 (GNUNET_YES == plc->is_host)
2206 ? cleanup_host ((struct Host *) plc)
2207 : cleanup_guest ((struct Guest *) plc);
2164} 2208}
2165 2209
2166 2210
@@ -2174,6 +2218,11 @@ handle_client_place_leave (void *cls,
2174 struct Client *c = cls; 2218 struct Client *c = cls;
2175 struct GNUNET_SERVICE_Client *client = c->client; 2219 struct GNUNET_SERVICE_Client *client = c->client;
2176 struct Place *plc = c->place; 2220 struct Place *plc = c->place;
2221
2222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2223 "got leave request from %s for place %s",
2224 plc->is_host? "host" : "slave",
2225 GNUNET_h2s (&plc->pub_key_hash));
2177 if (NULL == plc) 2226 if (NULL == plc)
2178 { 2227 {
2179 GNUNET_break (0); 2228 GNUNET_break (0);
@@ -2181,40 +2230,28 @@ handle_client_place_leave (void *cls,
2181 return; 2230 return;
2182 } 2231 }
2183 2232
2184 /* FIXME: remove all app subscriptions and leave this place */ 2233 if (GNUNET_YES != plc->is_disconnecting)
2185
2186 struct GNUNET_CONTAINER_MultiHashMap *
2187 place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, &plc->pub_key_hash);
2188 if (NULL != place_apps)
2189 { 2234 {
2190 GNUNET_CONTAINER_multihashmap_iterate (place_apps, app_places_entry_remove, plc); 2235 plc->is_disconnecting = GNUNET_YES;
2191 } 2236 if (plc->is_host)
2192 2237 {
2193 /* FIXME: disconnect from the network, but keep local connection for history access */ 2238 struct Host *host = plc->host;
2194 2239 GNUNET_assert (NULL != host);
2195 /* Disconnect all clients connected to the place */ 2240 GNUNET_PSYC_master_stop (host->master, GNUNET_NO, &place_leave_cb, plc);
2196 struct ClientListItem *cli = plc->clients_head, *next;
2197 while (NULL != cli)
2198 {
2199 GNUNET_CONTAINER_DLL_remove (plc->clients_head, plc->clients_tail, cli);
2200 GNUNET_SERVICE_client_drop (cli->client);
2201 next = cli->next;
2202 GNUNET_free (cli);
2203 cli = next;
2204 }
2205
2206 if (GNUNET_YES != plc->is_disconnected)
2207 {
2208 plc->is_disconnected = GNUNET_YES;
2209 if (NULL != plc->tmit_msgs_head)
2210 { /* Send pending messages to PSYC before cleanup. */
2211 psyc_transmit_message (plc);
2212 } 2241 }
2213 else 2242 else
2214 { 2243 {
2215 cleanup_place (plc); 2244 struct Guest *guest = plc->guest;
2245 GNUNET_assert (NULL != guest);
2246 GNUNET_PSYC_slave_part (guest->slave, GNUNET_NO, &place_leave_cb, plc);
2216 } 2247 }
2217 } 2248 }
2249 else
2250 {
2251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2252 "got leave request but place is already leaving\n");
2253 }
2254 GNUNET_SERVICE_client_continue (client);
2218} 2255}
2219 2256
2220 2257
@@ -2273,6 +2310,9 @@ handle_client_join_decision (void *cls,
2273 ? (struct GNUNET_PSYC_Message *) &dcsn[1] 2310 ? (struct GNUNET_PSYC_Message *) &dcsn[1]
2274 : NULL; 2311 : NULL;
2275 2312
2313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2314 "jcls.msg = %p\n",
2315 jcls.msg);
2276 struct GNUNET_HashCode slave_pub_hash; 2316 struct GNUNET_HashCode slave_pub_hash;
2277 GNUNET_CRYPTO_hash (&dcsn->slave_pub_key, sizeof (dcsn->slave_pub_key), 2317 GNUNET_CRYPTO_hash (&dcsn->slave_pub_key, sizeof (dcsn->slave_pub_key),
2278 &slave_pub_hash); 2318 &slave_pub_hash);
@@ -2302,10 +2342,11 @@ handle_client_join_decision (void *cls,
2302static void 2342static void
2303send_message_ack (struct Place *plc, struct GNUNET_SERVICE_Client *client) 2343send_message_ack (struct Place *plc, struct GNUNET_SERVICE_Client *client)
2304{ 2344{
2305 struct GNUNET_MessageHeader res; 2345 struct GNUNET_MQ_Envelope *env;
2306 res.size = htons (sizeof (res)); 2346
2307 res.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK); 2347 env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK);
2308 client_send_msg (client, &res); 2348 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
2349 env);
2309} 2350}
2310 2351
2311 2352
@@ -2437,7 +2478,6 @@ psyc_transmit_notify_data (void *cls, uint16_t *data_size, void *data)
2437 { 2478 {
2438 *data_size = 0; 2479 *data_size = 0;
2439 tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg); 2480 tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg);
2440 plc->is_disconnected = GNUNET_YES;
2441 GNUNET_SERVICE_client_drop (tmit_frag->client); 2481 GNUNET_SERVICE_client_drop (tmit_frag->client);
2442 GNUNET_SCHEDULER_add_now (&cleanup_place, plc); 2482 GNUNET_SCHEDULER_add_now (&cleanup_place, plc);
2443 return ret; 2483 return ret;
@@ -2479,11 +2519,7 @@ psyc_transmit_notify_data (void *cls, uint16_t *data_size, void *data)
2479 { 2519 {
2480 psyc_transmit_message (plc); 2520 psyc_transmit_message (plc);
2481 } 2521 }
2482 else if (GNUNET_YES == plc->is_disconnected) 2522 /* FIXME: handle partial message (when still in_transmit) */
2483 {
2484 /* FIXME: handle partial message (when still in_transmit) */
2485 cleanup_place (plc);
2486 }
2487 } 2523 }
2488 return ret; 2524 return ret;
2489} 2525}
@@ -2597,7 +2633,6 @@ psyc_transmit_notify_mod (void *cls, uint16_t *data_size, void *data,
2597 *data_size = 0; 2633 *data_size = 0;
2598 ret = GNUNET_SYSERR; 2634 ret = GNUNET_SYSERR;
2599 tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg); 2635 tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg);
2600 plc->is_disconnected = GNUNET_YES;
2601 GNUNET_SERVICE_client_drop (tmit_frag->client); 2636 GNUNET_SERVICE_client_drop (tmit_frag->client);
2602 GNUNET_SCHEDULER_add_now (&cleanup_place, plc); 2637 GNUNET_SCHEDULER_add_now (&cleanup_place, plc);
2603 } 2638 }
@@ -2862,26 +2897,26 @@ psyc_transmit_queue_message (struct Place *plc,
2862} 2897}
2863 2898
2864 2899
2865/** 2900///**
2866 * Cancel transmission of current message to PSYC. 2901// * Cancel transmission of current message to PSYC.
2867 * 2902// *
2868 * @param plc Place to send to. 2903// * @param plc Place to send to.
2869 * @param client Client the message originates from. 2904// * @param client Client the message originates from.
2870 */ 2905// */
2871static void 2906//static void
2872psyc_transmit_cancel (struct Place *plc, struct GNUNET_SERVICE_Client *client) 2907//psyc_transmit_cancel (struct Place *plc, struct GNUNET_SERVICE_Client *client)
2873{ 2908//{
2874 uint16_t type = GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL; 2909// uint16_t type = GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL;
2875 2910//
2876 struct GNUNET_MessageHeader msg; 2911// struct GNUNET_MessageHeader msg;
2877 msg.size = htons (sizeof (msg)); 2912// msg.size = htons (sizeof (msg));
2878 msg.type = htons (type); 2913// msg.type = htons (type);
2879 2914//
2880 psyc_transmit_queue_message (plc, client, sizeof (msg), &msg, type, type, NULL); 2915// psyc_transmit_queue_message (plc, client, sizeof (msg), &msg, type, type, NULL);
2881 psyc_transmit_message (plc); 2916// psyc_transmit_message (plc);
2882 2917//
2883 /* FIXME: cleanup */ 2918// /* FIXME: cleanup */
2884} 2919//}
2885 2920
2886 2921
2887static int 2922static int
@@ -2902,17 +2937,19 @@ handle_client_psyc_message (void *cls,
2902 struct Client *c = cls; 2937 struct Client *c = cls;
2903 struct GNUNET_SERVICE_Client *client = c->client; 2938 struct GNUNET_SERVICE_Client *client = c->client;
2904 struct Place *plc = c->place; 2939 struct Place *plc = c->place;
2940 int ret;
2941
2905 if (NULL == plc) 2942 if (NULL == plc)
2906 { 2943 {
2944 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2945 "received PSYC message for non-existing client %p\n",
2946 client);
2907 GNUNET_break (0); 2947 GNUNET_break (0);
2908 GNUNET_SERVICE_client_drop (client); 2948 GNUNET_SERVICE_client_drop (client);
2909 return; 2949 return;
2910 } 2950 }
2911
2912 int ret = GNUNET_SYSERR;
2913
2914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2915 "%p Received message from client.\n", plc); 2952 "%p Received message of type %d from client.\n", plc, ntohs (msg->type));
2916 GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, msg); 2953 GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, msg);
2917 2954
2918 if (GNUNET_YES != plc->is_ready) 2955 if (GNUNET_YES != plc->is_ready)
@@ -2933,20 +2970,19 @@ handle_client_psyc_message (void *cls,
2933 "%p Received message with invalid payload size (%u) from client.\n", 2970 "%p Received message with invalid payload size (%u) from client.\n",
2934 plc, psize); 2971 plc, psize);
2935 GNUNET_break (0); 2972 GNUNET_break (0);
2936 psyc_transmit_cancel (plc, client);
2937 GNUNET_SERVICE_client_drop (client); 2973 GNUNET_SERVICE_client_drop (client);
2938 return; 2974 return;
2939 } 2975 }
2940 2976
2941 uint16_t first_ptype = 0, last_ptype = 0; 2977 uint16_t first_ptype = 0;
2942 if (GNUNET_SYSERR 2978 uint16_t last_ptype = 0;
2943 == GNUNET_PSYC_receive_check_parts (psize, (const char *) &msg[1], 2979 if (GNUNET_SYSERR ==
2944 &first_ptype, &last_ptype)) 2980 GNUNET_PSYC_receive_check_parts (psize, (const char *) &msg[1],
2981 &first_ptype, &last_ptype))
2945 { 2982 {
2946 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2983 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2947 "%p Received invalid message part from client.\n", plc); 2984 "%p Received invalid message part from client.\n", plc);
2948 GNUNET_break (0); 2985 GNUNET_break (0);
2949 psyc_transmit_cancel (plc, client);
2950 GNUNET_SERVICE_client_drop (client); 2986 GNUNET_SERVICE_client_drop (client);
2951 return; 2987 return;
2952 } 2988 }
@@ -2963,20 +2999,19 @@ handle_client_psyc_message (void *cls,
2963 c->tmit_msg = NULL; 2999 c->tmit_msg = NULL;
2964 ret = psyc_transmit_message (plc); 3000 ret = psyc_transmit_message (plc);
2965 } 3001 }
2966 3002 else
3003 {
3004 ret = GNUNET_SYSERR;
3005 }
2967 if (GNUNET_OK != ret) 3006 if (GNUNET_OK != ret)
2968 { 3007 {
2969 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3008 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2970 "%p Received invalid message part from client.\n", plc); 3009 "%p Received invalid message part from client.\n", plc);
2971 GNUNET_break (0); 3010 GNUNET_break (0);
2972 psyc_transmit_cancel (plc, client);
2973 ret = GNUNET_SYSERR;
2974 }
2975
2976 if (GNUNET_OK == ret)
2977 GNUNET_SERVICE_client_continue (client);
2978 else
2979 GNUNET_SERVICE_client_drop (client); 3011 GNUNET_SERVICE_client_drop (client);
3012 return;
3013 }
3014 GNUNET_SERVICE_client_continue (client);
2980} 3015}
2981 3016
2982 3017
@@ -3006,7 +3041,7 @@ psyc_recv_history_message (void *cls, const struct GNUNET_PSYC_MessageHeader *ms
3006 GNUNET_memcpy (&res[1], msg, size); 3041 GNUNET_memcpy (&res[1], msg, size);
3007 3042
3008 /** @todo FIXME: send only to requesting client */ 3043 /** @todo FIXME: send only to requesting client */
3009 place_send_msg (plc, &res->header); 3044 place_send_msg (plc, GNUNET_MQ_msg_copy (&res->header));
3010 3045
3011 GNUNET_free (res); 3046 GNUNET_free (res);
3012} 3047}
@@ -3108,29 +3143,24 @@ psyc_recv_state_var (void *cls,
3108 uint32_t value_size, 3143 uint32_t value_size,
3109 uint32_t full_value_size) 3144 uint32_t full_value_size)
3110{ 3145{
3146 struct GNUNET_OperationResultMessage *result_msg;
3147 struct GNUNET_MQ_Envelope *env;
3111 struct OperationClosure *opcls = cls; 3148 struct OperationClosure *opcls = cls;
3112 struct Client *c = opcls->client; 3149 struct Client *c = opcls->client;
3113 struct Place *plc = c->place; 3150 struct Place *plc = c->place;
3151 uint16_t size = ntohs (mod->size);
3114 3152
3115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3116 "%p Received state variable %s from PSYC\n", 3154 "%p Received state variable %s from PSYC\n",
3117 plc, name); 3155 plc, name);
3118 3156 env = GNUNET_MQ_msg_extra (result_msg,
3119 uint16_t size = ntohs (mod->size); 3157 size,
3120 3158 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT);
3121 struct GNUNET_OperationResultMessage * 3159 result_msg->op_id = opcls->op_id;
3122 res = GNUNET_malloc (sizeof (*res) + size); 3160 result_msg->result_code = GNUNET_htonll (GNUNET_OK);
3123 res->header.size = htons (sizeof (*res) + size); 3161 GNUNET_memcpy (&result_msg[1], mod, size);
3124 res->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT);
3125 res->op_id = opcls->op_id;
3126 res->result_code = GNUNET_htonll (GNUNET_OK);
3127
3128 GNUNET_memcpy (&res[1], mod, size);
3129
3130 /** @todo FIXME: send only to requesting client */ 3162 /** @todo FIXME: send only to requesting client */
3131 place_send_msg (plc, &res->header); 3163 place_send_msg (plc, env);
3132
3133 GNUNET_free (res);
3134} 3164}
3135 3165
3136 3166
@@ -3184,7 +3214,7 @@ handle_client_state_get (void *cls,
3184 uint16_t size = ntohs (req->header.size); 3214 uint16_t size = ntohs (req->header.size);
3185 const char *name = (const char *) &req[1]; 3215 const char *name = (const char *) &req[1];
3186 3216
3187 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3188 "%p State get #%" PRIu64 ": %s\n", 3218 "%p State get #%" PRIu64 ": %s\n",
3189 plc, GNUNET_ntohll (req->op_id), name); 3219 plc, GNUNET_ntohll (req->op_id), name);
3190 3220
@@ -3382,7 +3412,7 @@ path_basename (const char *path)
3382 if (NULL != basename) 3412 if (NULL != basename)
3383 basename++; 3413 basename++;
3384 3414
3385 if (NULL == basename || '\0' == basename) 3415 if (NULL == basename || '\0' == *basename)
3386 return NULL; 3416 return NULL;
3387 3417
3388 return basename; 3418 return basename;
@@ -3468,7 +3498,10 @@ file_place_load (void *cls, const char *place_filename)
3468 return GNUNET_OK; 3498 return GNUNET_OK;
3469 } 3499 }
3470 3500
3471 app_place_add (plcls->app_id, ereq); 3501 if (GNUNET_SYSERR == app_place_add (plcls->app_id, ereq))
3502 {
3503 GNUNET_assert (0);
3504 }
3472 GNUNET_free (ereq); 3505 GNUNET_free (ereq);
3473 return GNUNET_OK; 3506 return GNUNET_OK;
3474} 3507}
@@ -3523,6 +3556,10 @@ identity_recv_ego (void *cls, struct GNUNET_IDENTITY_Ego *id_ego,
3523 if (NULL == id_ego) // end of initial list of egos 3556 if (NULL == id_ego) // end of initial list of egos
3524 return; 3557 return;
3525 3558
3559 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3560 "social service received ego %s\n",
3561 name);
3562
3526 struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key; 3563 struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key;
3527 GNUNET_IDENTITY_ego_get_public_key (id_ego, &ego_pub_key); 3564 GNUNET_IDENTITY_ego_get_public_key (id_ego, &ego_pub_key);
3528 3565
@@ -3571,6 +3608,9 @@ run (void *cls,
3571 const struct GNUNET_CONFIGURATION_Handle *c, 3608 const struct GNUNET_CONFIGURATION_Handle *c,
3572 struct GNUNET_SERVICE_Handle *svc) 3609 struct GNUNET_SERVICE_Handle *svc)
3573{ 3610{
3611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3612 "starting social service\n");
3613
3574 cfg = c; 3614 cfg = c;
3575 service = svc; 3615 service = svc;
3576 GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer); 3616 GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
@@ -3583,7 +3623,7 @@ run (void *cls,
3583 apps = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 3623 apps = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
3584 places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO); 3624 places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
3585 apps_places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO); 3625 apps_places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
3586 places_apps = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO); 3626 //places_apps = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
3587 3627
3588 id = GNUNET_IDENTITY_connect (cfg, &identity_recv_ego, NULL); 3628 id = GNUNET_IDENTITY_connect (cfg, &identity_recv_ego, NULL);
3589 gns = GNUNET_GNS_connect (cfg); 3629 gns = GNUNET_GNS_connect (cfg);