aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2015-11-18 22:13:27 +0000
committerGabor X Toth <*@tg-x.net>2015-11-18 22:13:27 +0000
commitad0201797ed84806a0a42fe3435dd56bd2c69ae5 (patch)
tree83a04545e9d8dc1799892ca6c37b3af083b0e7bd /src
parentaba4cac0f08ecb17df34e375337090b00f457763 (diff)
downloadgnunet-ad0201797ed84806a0a42fe3435dd56bd2c69ae5.tar.gz
gnunet-ad0201797ed84806a0a42fe3435dd56bd2c69ae5.zip
social: store/load entered places & notify clients about them
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_protocols.h4
-rw-r--r--src/include/gnunet_social_service.h73
-rw-r--r--src/social/gnunet-service-social.c499
-rw-r--r--src/social/social.h14
-rw-r--r--src/social/social_api.c187
-rw-r--r--src/social/test_social.c2
6 files changed, 697 insertions, 82 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 7ec3ceb70..5ae440349 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2616,6 +2616,10 @@ extern "C"
2616/** C->S->P: decision about an entry request */ 2616/** C->S->P: decision about an entry request */
2617#define GNUNET_MESSAGE_TYPE_SOCIAL_ENTRY_DECISION 846 2617#define GNUNET_MESSAGE_TYPE_SOCIAL_ENTRY_DECISION 846
2618 2618
2619/** C->S: listen for places */
2620#define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN 850
2621
2622
2619/******************************************************************************* 2623/*******************************************************************************
2620 * X-VINE DHT messages 2624 * X-VINE DHT messages
2621 ******************************************************************************/ 2625 ******************************************************************************/
diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h
index edb762a1e..21c073256 100644
--- a/src/include/gnunet_social_service.h
+++ b/src/include/gnunet_social_service.h
@@ -35,6 +35,7 @@ extern "C"
35#endif 35#endif
36#endif 36#endif
37 37
38#include <stdint.h>
38#include "gnunet_util_lib.h" 39#include "gnunet_util_lib.h"
39#include "gnunet_env_lib.h" 40#include "gnunet_env_lib.h"
40#include "gnunet_identity_service.h" 41#include "gnunet_identity_service.h"
@@ -73,7 +74,6 @@ struct GNUNET_SOCIAL_Guest;
73 */ 74 */
74struct GNUNET_SOCIAL_Slicer; 75struct GNUNET_SOCIAL_Slicer;
75 76
76
77/** 77/**
78 * Function called upon receiving a message indicating a call to a @e method. 78 * Function called upon receiving a message indicating a call to a @e method.
79 * 79 *
@@ -982,8 +982,8 @@ GNUNET_SOCIAL_place_look_cancel (struct GNUNET_SOCIAL_LookHandle *lh);
982 * Ego. 982 * Ego.
983 * @param name 983 * @param name
984 * The name for the PKEY record to put in the zone. 984 * The name for the PKEY record to put in the zone.
985 * @param pub_key 985 * @param nym_pub_key
986 * Public key to add. 986 * Public key of nym to add.
987 * @param expiration_time 987 * @param expiration_time
988 * Expiration time of the record, use 0 to remove the record. 988 * Expiration time of the record, use 0 to remove the record.
989 * @param result_cb 989 * @param result_cb
@@ -995,12 +995,77 @@ void
995GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg, 995GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg,
996 const struct GNUNET_IDENTITY_Ego *ego, 996 const struct GNUNET_IDENTITY_Ego *ego,
997 const char *name, 997 const char *name,
998 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key, 998 const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key,
999 struct GNUNET_TIME_Absolute expiration_time, 999 struct GNUNET_TIME_Absolute expiration_time,
1000 GNUNET_NAMESTORE_ContinuationWithStatus result_cb, 1000 GNUNET_NAMESTORE_ContinuationWithStatus result_cb,
1001 void *result_cls); 1001 void *result_cls);
1002 1002
1003 1003
1004/**
1005 * Handle for place notifications.
1006 */
1007struct GNUNET_SOCIAL_PlaceListenHandle;
1008
1009
1010/**
1011 * Notification about a place entered as host.
1012 */
1013typedef void
1014(*GNUNET_SOCIAL_PlaceNotifyHostCallback) (void *cls,
1015 const struct GNUNET_CRYPTO_EddsaPrivateKey *place_key,
1016 enum GNUNET_PSYC_Policy policy);
1017
1018
1019/**
1020 * Notification about a place entered as guest.
1021 */
1022typedef void
1023(*GNUNET_SOCIAL_PlaceNotifyGuestCallback) (void *cls,
1024 const struct GNUNET_CRYPTO_EddsaPublicKey *place_key,
1025 const struct GNUNET_PeerIdentity *origin,
1026 uint32_t relay_count,
1027 const struct GNUNET_PeerIdentity *relays,
1028 const struct GNUNET_PSYC_Message *entry_msg);
1029
1030
1031/**
1032 * Start listening for entered places as host or guest.
1033 *
1034 * The @notify_host and @notify_guest functions are
1035 * initially called with the full list of entered places,
1036 * then later each time a new place is entered.
1037 *
1038 * @param cfg
1039 * Configuration.
1040 * @param ego
1041 * Listen for places of this ego.
1042 * @param notify_host
1043 * Function to notify about a place entered as host.
1044 * @param notify_guest
1045 * Function to notify about a place entered as guest..
1046 * @param notify_cls
1047 * Closure for the callbacks.
1048 *
1049 * @return Handle that can be used to stop listening.
1050 */
1051struct GNUNET_SOCIAL_PlaceListenHandle *
1052GNUNET_SOCIAL_place_listen_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
1053 const struct GNUNET_IDENTITY_Ego *ego,
1054 GNUNET_SOCIAL_PlaceNotifyHostCallback notify_host,
1055 GNUNET_SOCIAL_PlaceNotifyGuestCallback notify_guest,
1056 void *notify_cls);
1057
1058
1059/**
1060 * Stop listening for entered places.
1061 *
1062 * @param h
1063 * Listen handle.
1064 */
1065void
1066GNUNET_SOCIAL_place_listen_stop (struct GNUNET_SOCIAL_PlaceListenHandle *h);
1067
1068
1004#if 0 /* keep Emacsens' auto-indent happy */ 1069#if 0 /* keep Emacsens' auto-indent happy */
1005{ 1070{
1006#endif 1071#endif
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c
index bf147d3ba..aace01fed 100644
--- a/src/social/gnunet-service-social.c
+++ b/src/social/gnunet-service-social.c
@@ -54,22 +54,39 @@ static struct GNUNET_SERVER_NotificationContext *nc;
54 54
55/** 55/**
56 * All connected hosts. 56 * All connected hosts.
57 * Place's pub_key_hash -> struct Host 57 * H(place_pub_key) -> struct Host
58 */ 58 */
59static struct GNUNET_CONTAINER_MultiHashMap *hosts; 59static struct GNUNET_CONTAINER_MultiHashMap *hosts;
60 60
61/** 61/**
62 * All connected guests. 62 * All connected guests.
63 * Place's pub_key_hash -> struct Guest 63 * H(place_pub_key) -> struct Guest
64 */ 64 */
65static struct GNUNET_CONTAINER_MultiHashMap *guests; 65static struct GNUNET_CONTAINER_MultiHashMap *guests;
66 66
67/** 67/**
68 * Connected guests per place. 68 * Connected guests per place.
69 * Place's pub_key_hash -> Guest's pub_key -> struct Guest 69 * H(place_pub_key) -> Guest's pub_key -> struct Guest
70 */ 70 */
71static struct GNUNET_CONTAINER_MultiHashMap *place_guests; 71static struct GNUNET_CONTAINER_MultiHashMap *place_guests;
72 72
73/**
74 * Places entered as host or guest.
75 * H(place_pub_key) -> struct HostEnterRequest OR struct GuestEnterRequest
76 */
77static struct GNUNET_CONTAINER_MultiHashMap *places_entered;
78
79/**
80 * Place listener clients.
81 * H(ego_pub_key) -> struct PlaceListener
82 */
83static struct GNUNET_CONTAINER_MultiHashMap *place_listeners;
84
85/**
86 * Directory for storing places.
87 */
88static char *dir_places;
89
73 90
74/** 91/**
75 * Message fragment transmission queue. 92 * Message fragment transmission queue.
@@ -275,6 +292,9 @@ struct Guest
275}; 292};
276 293
277 294
295/**
296 * Context for host/guest client.
297 */
278struct Client 298struct Client
279{ 299{
280 /** 300 /**
@@ -287,6 +307,18 @@ struct Client
287 * by this client. 307 * by this client.
288 */ 308 */
289 struct MessageTransmitQueue *tmit_msg; 309 struct MessageTransmitQueue *tmit_msg;
310
311 /**
312 * Ego key for listener clients;
313 */
314 struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key;
315};
316
317
318struct PlaceListener
319{
320 struct ClientListItem *clients_head;
321 struct ClientListItem *clients_tail;
290}; 322};
291 323
292 324
@@ -419,6 +451,9 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
419 } 451 }
420 452
421 struct Place *plc = ctx->plc; 453 struct Place *plc = ctx->plc;
454 if (NULL == plc)
455 return; // place listener client, nothing to do
456
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 457 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
423 "%p Client (%s) disconnected from place %s\n", 458 "%p Client (%s) disconnected from place %s\n",
424 plc, (GNUNET_YES == plc->is_host) ? "host" : "guest", 459 plc, (GNUNET_YES == plc->is_host) ? "host" : "guest",
@@ -623,36 +658,144 @@ place_init (struct Place *plc)
623 658
624 659
625/** 660/**
626 * Handle a connecting client entering a place as host. 661 * Add place to places_entered hash map.
662 *
663 * @param ego_pub_hash
664 * H(ego_pub_key)
665 * @param place_pub_hash
666 * H(place_pub_key)
667 * @param msg
668 * Entry message.
669 *
670 * @return Return value of GNUNET_CONTAINER_multihashmap_put ()
671 */
672static int
673place_add (const struct GNUNET_HashCode *ego_pub_hash,
674 const struct GNUNET_HashCode *place_pub_hash,
675 const struct GNUNET_MessageHeader *msg)
676{
677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
678 "Adding place to hashmap:\n");
679 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
680 " ego_pub_hash = %s\n", GNUNET_h2s (ego_pub_hash));
681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
682 " place_pub_hash = %s\n", GNUNET_h2s (place_pub_hash));
683
684 struct GNUNET_CONTAINER_MultiHashMap *
685 ego_places = GNUNET_CONTAINER_multihashmap_get (places_entered, ego_pub_hash);
686 if (NULL == ego_places)
687 {
688 ego_places = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
689 GNUNET_CONTAINER_multihashmap_put (places_entered, ego_pub_hash, ego_places,
690 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
691 }
692
693 struct GNUNET_MessageHeader *msg_old, *msg_new;
694 if (NULL != (msg_old = GNUNET_CONTAINER_multihashmap_get (ego_places, place_pub_hash)))
695 {
696 GNUNET_free (msg_old);
697 GNUNET_CONTAINER_multihashmap_remove_all (ego_places, place_pub_hash);
698 }
699
700 uint16_t msg_size = ntohs (msg->size);
701 msg_new = GNUNET_malloc (msg_size);
702 memcpy (msg_new, msg, msg_size);
703 int ret = GNUNET_CONTAINER_multihashmap_put (ego_places, place_pub_hash, msg_new,
704 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
705 if (GNUNET_OK != ret)
706 GNUNET_break (0);
707 return ret;
708}
709
710
711/**
712 * Save place entry message to disk.
713 *
714 * @param ego_key
715 * Private key of ego.
716 * @param place_pub_hash
717 * Hash of public key of place.
718 * @param msg
719 * Entry message.
627 */ 720 */
628static void 721static void
629client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, 722place_save (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ego_key,
630 const struct GNUNET_MessageHeader *msg) 723 const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub,
724 const struct GNUNET_MessageHeader *msg)
631{ 725{
632 const struct HostEnterRequest *req 726 if (NULL == dir_places)
633 = (const struct HostEnterRequest *) msg; 727 return;
634 728
635 struct GNUNET_CRYPTO_EddsaPublicKey pub_key; 729 struct GNUNET_HashCode place_pub_hash;
636 struct GNUNET_HashCode pub_key_hash; 730 GNUNET_CRYPTO_hash (place_pub, sizeof (place_pub), &place_pub_hash);
731
732 struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub;
733 struct GNUNET_HashCode ego_pub_hash;
734 GNUNET_CRYPTO_ecdsa_key_get_public (ego_key, &ego_pub);
735 GNUNET_CRYPTO_hash (&ego_pub, sizeof (ego_pub), &ego_pub_hash);
736
737 place_add (&ego_pub_hash, &place_pub_hash, msg);
738
739 char *ego_pub_hash_str = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1);
740 char *place_pub_hash_str = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1);
741 memcpy (ego_pub_hash_str, GNUNET_h2s_full (&ego_pub_hash), sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
742 memcpy (place_pub_hash_str, GNUNET_h2s_full (&place_pub_hash), sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
743
744 char *filename = GNUNET_malloc (strlen (dir_places) + 1
745 + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1
746 + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1);
747 GNUNET_asprintf (&filename,
748 "%s%s%s%s%s",
749 dir_places, DIR_SEPARATOR_STR,
750 ego_pub_hash_str, DIR_SEPARATOR_STR,
751 place_pub_hash_str);
752
753 GNUNET_DISK_directory_create_for_file (filename);
754 if (GNUNET_DISK_fn_write (filename, msg, ntohs (msg->size),
755 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE) < 0)
756 {
757 GNUNET_break (0);
758 }
637 759
638 GNUNET_CRYPTO_eddsa_key_get_public (&req->place_key, &pub_key); 760 GNUNET_free (ego_pub_hash_str);
639 GNUNET_CRYPTO_hash (&pub_key, sizeof (pub_key), &pub_key_hash); 761 GNUNET_free (place_pub_hash_str);
762 GNUNET_free (filename);
763}
640 764
641 struct Host *
642 hst = GNUNET_CONTAINER_multihashmap_get (hosts, &pub_key_hash);
643 struct Place *plc;
644 765
766/**
767 * Enter place as host.
768 *
769 * @param req
770 * Entry request.
771 * @param[out] ret_hst
772 * Returned Host struct.
773 *
774 * @return #GNUNET_YES if the host entered the place just now,
775 * #GNUNET_NO if the place is already entered.
776 */
777static int
778host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst)
779{
780 int ret = GNUNET_NO;
781 struct GNUNET_CRYPTO_EddsaPublicKey place_pub;
782 struct GNUNET_HashCode place_pub_hash;
783
784 GNUNET_CRYPTO_eddsa_key_get_public (&hreq->place_key, &place_pub);
785 GNUNET_CRYPTO_hash (&place_pub, sizeof (place_pub), &place_pub_hash);
786
787 struct Host *hst = GNUNET_CONTAINER_multihashmap_get (hosts, &place_pub_hash);
645 if (NULL == hst) 788 if (NULL == hst)
646 { 789 {
647 hst = GNUNET_new (struct Host); 790 hst = GNUNET_new (struct Host);
648 hst->policy = ntohl (req->policy); 791 hst->policy = ntohl (hreq->policy);
649 hst->priv_key = req->place_key; 792 hst->priv_key = hreq->place_key;
650 hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 793 hst->join_reqs = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
651 794
652 plc = &hst->plc; 795 struct Place *plc = &hst->plc;
653 plc->is_host = GNUNET_YES; 796 plc->is_host = GNUNET_YES;
654 plc->pub_key = pub_key; 797 plc->pub_key = place_pub;
655 plc->pub_key_hash = pub_key_hash; 798 plc->pub_key_hash = place_pub_hash;
656 place_init (plc); 799 place_init (plc);
657 800
658 GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc, 801 GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc,
@@ -662,8 +805,34 @@ client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client,
662 &psyc_recv_join_request, 805 &psyc_recv_join_request,
663 &psyc_recv_message, NULL, hst); 806 &psyc_recv_message, NULL, hst);
664 hst->plc.channel = GNUNET_PSYC_master_get_channel (hst->master); 807 hst->plc.channel = GNUNET_PSYC_master_get_channel (hst->master);
808 ret = GNUNET_YES;
665 } 809 }
666 else 810
811 if (NULL != ret_hst)
812 *ret_hst = hst;
813 return ret;
814}
815
816
817/**
818 * Handle a connecting client entering a place as host.
819 */
820static void
821client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client,
822 const struct GNUNET_MessageHeader *msg)
823{
824 const struct HostEnterRequest *hreq
825 = (const struct HostEnterRequest *) msg;
826 struct Place *plc;
827 struct Host *hst;
828
829 switch (host_enter (hreq, &hst))
830 {
831 case GNUNET_YES:
832 plc = &hst->plc;
833 break;
834
835 case GNUNET_NO:
667 { 836 {
668 plc = &hst->plc; 837 plc = &hst->plc;
669 838
@@ -676,8 +845,18 @@ client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client,
676 GNUNET_SERVER_notification_context_add (nc, client); 845 GNUNET_SERVER_notification_context_add (nc, client);
677 GNUNET_SERVER_notification_context_unicast (nc, client, &res.header, 846 GNUNET_SERVER_notification_context_unicast (nc, client, &res.header,
678 GNUNET_NO); 847 GNUNET_NO);
848 break;
849 }
850 case GNUNET_SYSERR:
851 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
852 return;
679 } 853 }
680 854
855 struct GNUNET_CRYPTO_EddsaPublicKey place_pub;
856 GNUNET_CRYPTO_eddsa_key_get_public (&hreq->place_key, &place_pub);
857
858 place_save (&hreq->host_key, &place_pub, msg);
859
681 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 860 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
682 "%p Client connected as host to place %s.\n", 861 "%p Client connected as host to place %s.\n",
683 hst, GNUNET_h2s (&plc->pub_key_hash)); 862 hst, GNUNET_h2s (&plc->pub_key_hash));
@@ -694,74 +873,78 @@ client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client,
694 873
695 874
696/** 875/**
697 * Handle a connecting client entering a place as guest. 876 * Enter place as guest.
877 *
878 * @param req
879 * Entry request.
880 * @param[out] ret_gst
881 * Returned Guest struct.
882 *
883 * @return #GNUNET_YES if the guest entered the place just now,
884 * #GNUNET_NO if the place is already entered.
698 */ 885 */
699static void 886static int
700client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, 887guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
701 const struct GNUNET_MessageHeader *msg)
702{ 888{
703 const struct GuestEnterRequest *req 889 int ret = GNUNET_NO;
704 = (const struct GuestEnterRequest *) msg; 890 uint16_t greq_size = ntohs (greq->header.size);
705 uint16_t req_size = ntohs (req->header.size);
706 891
707 struct GNUNET_CRYPTO_EcdsaPublicKey gst_pub_key; 892 struct GNUNET_CRYPTO_EcdsaPublicKey gst_pub_key;
708 struct GNUNET_HashCode pub_key_hash, gst_pub_key_hash; 893 struct GNUNET_HashCode place_pub_hash, gst_pub_key_hash;
709 894 GNUNET_CRYPTO_ecdsa_key_get_public (&greq->guest_key, &gst_pub_key);
710 GNUNET_CRYPTO_ecdsa_key_get_public (&req->guest_key, &gst_pub_key);
711 GNUNET_CRYPTO_hash (&gst_pub_key, sizeof (gst_pub_key), &gst_pub_key_hash); 895 GNUNET_CRYPTO_hash (&gst_pub_key, sizeof (gst_pub_key), &gst_pub_key_hash);
712 GNUNET_CRYPTO_hash (&req->place_key, sizeof (req->place_key), &pub_key_hash); 896 GNUNET_CRYPTO_hash (&greq->place_key, sizeof (greq->place_key), &place_pub_hash);
713 897
714 struct GNUNET_CONTAINER_MultiHashMap * 898 struct GNUNET_CONTAINER_MultiHashMap *
715 plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, &pub_key_hash); 899 plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests, &place_pub_hash);
716 struct Guest *gst = NULL; 900 struct Guest *gst = NULL;
717 struct Place *plc; 901 struct Place *plc;
718 902
719 if (NULL != plc_gst) 903 if (NULL != plc_gst)
720 {
721 gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &gst_pub_key_hash); 904 gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &gst_pub_key_hash);
722 } 905
723 if (NULL == gst || NULL == gst->slave) 906 if (NULL == gst || NULL == gst->slave)
724 { 907 {
725 gst = GNUNET_new (struct Guest); 908 gst = GNUNET_new (struct Guest);
726 gst->priv_key = req->guest_key; 909 gst->priv_key = greq->guest_key;
727 gst->pub_key = gst_pub_key; 910 gst->pub_key = gst_pub_key;
728 gst->pub_key_hash = gst_pub_key_hash; 911 gst->pub_key_hash = gst_pub_key_hash;
729 gst->origin = req->origin; 912 gst->origin = greq->origin;
730 gst->relay_count = ntohl (req->relay_count); 913 gst->relay_count = ntohl (greq->relay_count);
731 914
732 const struct GNUNET_PeerIdentity * 915 const struct GNUNET_PeerIdentity *relays = NULL;
733 relays = (const struct GNUNET_PeerIdentity *) &req[1];
734 uint16_t relay_size = gst->relay_count * sizeof (*relays); 916 uint16_t relay_size = gst->relay_count * sizeof (*relays);
917 if (0 < relay_size)
918 relays = (const struct GNUNET_PeerIdentity *) &greq[1];
735 struct GNUNET_PSYC_Message *join_msg = NULL; 919 struct GNUNET_PSYC_Message *join_msg = NULL;
736 uint16_t join_msg_size = 0; 920 uint16_t join_msg_size = 0;
737 921
738 if (sizeof (*req) + relay_size + sizeof (struct GNUNET_MessageHeader) 922 if (sizeof (*greq) + relay_size + sizeof (struct GNUNET_MessageHeader)
739 <= req_size) 923 <= greq_size)
740 { 924 {
741 join_msg = (struct GNUNET_PSYC_Message *) 925 join_msg = (struct GNUNET_PSYC_Message *)
742 (((char *) &req[1]) + relay_size); 926 (((char *) &greq[1]) + relay_size);
743 join_msg_size = ntohs (join_msg->header.size); 927 join_msg_size = ntohs (join_msg->header.size);
744 } 928 }
745 if (sizeof (*req) + relay_size + join_msg_size != req_size) 929 if (sizeof (*greq) + relay_size + join_msg_size != greq_size)
746 { 930 {
747 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 931 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
748 "%u + %u + %u != %u\n", 932 "%u + %u + %u != %u\n",
749 sizeof (*req), relay_size, join_msg_size, req_size); 933 sizeof (*greq), relay_size, join_msg_size, greq_size);
750 GNUNET_break (0); 934 GNUNET_break (0);
751 GNUNET_SERVER_client_disconnect (client);
752 GNUNET_free (gst); 935 GNUNET_free (gst);
753 return; 936 return GNUNET_SYSERR;
754 } 937 }
755 if (0 < gst->relay_count) 938 if (0 < gst->relay_count)
756 { 939 {
757 gst->relays = GNUNET_malloc (relay_size); 940 gst->relays = GNUNET_malloc (relay_size);
758 memcpy (gst->relays, &req[1], relay_size); 941 memcpy (gst->relays, &greq[1], relay_size);
759 } 942 }
760 943
761 plc = &gst->plc; 944 plc = &gst->plc;
762 plc->is_host = GNUNET_NO; 945 plc->is_host = GNUNET_NO;
763 plc->pub_key = req->place_key; 946 plc->pub_key = greq->place_key;
764 plc->pub_key_hash = pub_key_hash; 947 plc->pub_key_hash = place_pub_hash;
765 place_init (plc); 948 place_init (plc);
766 949
767 if (NULL == plc_gst) 950 if (NULL == plc_gst)
@@ -771,17 +954,43 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client,
771 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 954 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
772 } 955 }
773 (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &gst->pub_key_hash, gst, 956 (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &gst->pub_key_hash, gst,
774 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 957 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
775 (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst, 958 (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst,
776 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 959 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
777 gst->slave 960 gst->slave
778 = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &gst->priv_key, 961 = GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &gst->priv_key,
779 &gst->origin, gst->relay_count, gst->relays, 962 &gst->origin, gst->relay_count, gst->relays,
780 &psyc_recv_message, NULL, &psyc_slave_connected, 963 &psyc_recv_message, NULL, &psyc_slave_connected,
781 &psyc_recv_join_dcsn, gst, join_msg); 964 &psyc_recv_join_dcsn, gst, join_msg);
782 gst->plc.channel = GNUNET_PSYC_slave_get_channel (gst->slave); 965 gst->plc.channel = GNUNET_PSYC_slave_get_channel (gst->slave);
966 ret = GNUNET_YES;
783 } 967 }
784 else 968
969 if (NULL != ret_gst)
970 *ret_gst = gst;
971 return ret;
972}
973
974
975/**
976 * Handle a connecting client entering a place as guest.
977 */
978static void
979client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client,
980 const struct GNUNET_MessageHeader *msg)
981{
982 const struct GuestEnterRequest *
983 greq = (const struct GuestEnterRequest *) msg;
984 struct Guest *gst = NULL;
985 struct Place *plc = NULL;
986
987 switch (guest_enter (greq, &gst))
988 {
989 case GNUNET_YES:
990 plc = &gst->plc;
991 break;
992
993 case GNUNET_NO:
785 { 994 {
786 plc = &gst->plc; 995 plc = &gst->plc;
787 996
@@ -801,11 +1010,18 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client,
801 &gst->join_dcsn->header, 1010 &gst->join_dcsn->header,
802 GNUNET_NO); 1011 GNUNET_NO);
803 } 1012 }
1013 break;
1014 }
1015 case GNUNET_SYSERR:
1016 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1017 return;
804 } 1018 }
805 1019
1020 place_save (&greq->guest_key, &greq->place_key, msg);
1021
806 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1022 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
807 "%p Client connected as guest to place %s.\n", 1023 "%p Client connected as guest to place %s.\n",
808 gst, GNUNET_h2s (&plc->pub_key_hash)); 1024 gst, GNUNET_h2s (&gst->plc.pub_key_hash));
809 1025
810 struct ClientListItem *cli = GNUNET_new (struct ClientListItem); 1026 struct ClientListItem *cli = GNUNET_new (struct ClientListItem);
811 cli->client = client; 1027 cli->client = client;
@@ -818,6 +1034,94 @@ client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client,
818} 1034}
819 1035
820 1036
1037void
1038place_notify (struct GNUNET_MessageHeader *msg,
1039 struct GNUNET_SERVER_Client *client)
1040{
1041 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1042 "%p Sending place notification of type %u to client.\n",
1043 client, ntohs (msg->type));
1044
1045 uint16_t msg_size = ntohs (msg->size);
1046 struct GNUNET_CRYPTO_EcdsaPublicKey place_pub;
1047
1048 switch (ntohs (msg->type))
1049 {
1050 case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER:
1051 if (msg_size < sizeof (struct HostEnterRequest))
1052 return;
1053 struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg;
1054 GNUNET_CRYPTO_ecdsa_key_get_public (&hreq->host_key, &place_pub);
1055 break;
1056
1057 case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER:
1058 if (msg_size < sizeof (struct GuestEnterRequest))
1059 return;
1060 struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg;
1061 GNUNET_CRYPTO_ecdsa_key_get_public (&greq->guest_key, &place_pub);
1062 break;
1063
1064 default:
1065 return;
1066 }
1067
1068 GNUNET_SERVER_notification_context_add (nc, client);
1069 GNUNET_SERVER_notification_context_unicast (nc, client, msg,
1070 GNUNET_NO);
1071}
1072
1073
1074int
1075map_entry_place (void *cls, const struct GNUNET_HashCode *key, void *value)
1076{
1077 place_notify (value, cls);
1078 return GNUNET_YES;
1079}
1080
1081
1082/**
1083 * Handle a connecting client listening for entered places.
1084 */
1085static void
1086client_recv_place_listen (void *cls, struct GNUNET_SERVER_Client *client,
1087 const struct GNUNET_MessageHeader *msg)
1088{
1089 const struct PlaceListenRequest *req
1090 = (const struct PlaceListenRequest *) msg;
1091
1092 struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub;
1093 struct GNUNET_HashCode ego_pub_hash;
1094
1095 GNUNET_CRYPTO_ecdsa_key_get_public (&req->ego_key, &ego_pub);
1096 GNUNET_CRYPTO_hash (&ego_pub, sizeof (ego_pub), &ego_pub_hash);
1097
1098 struct GNUNET_CONTAINER_MultiHashMap *
1099 ego_places = GNUNET_CONTAINER_multihashmap_get (places_entered, &ego_pub_hash);
1100 if (NULL != ego_places)
1101 GNUNET_CONTAINER_multihashmap_iterate (ego_places, map_entry_place, client);
1102
1103 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1104 "%p Client connected to listen for entered places of ego %s.\n",
1105 NULL, GNUNET_h2s (&ego_pub_hash));
1106
1107 struct ClientListItem *cli = GNUNET_new (struct ClientListItem);
1108 cli->client = client;
1109 struct PlaceListener *pl = GNUNET_CONTAINER_multihashmap_get (place_listeners,
1110 &ego_pub_hash);
1111 if (NULL == pl) {
1112 pl = GNUNET_malloc (sizeof (*pl));
1113 (void) GNUNET_CONTAINER_multihashmap_put (place_listeners, &ego_pub_hash, pl,
1114 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1115 }
1116 GNUNET_CONTAINER_DLL_insert (pl->clients_head, pl->clients_tail, cli);
1117
1118 struct Client *ctx = GNUNET_new (struct Client);
1119 ctx->ego_key = req->ego_key;
1120 GNUNET_SERVER_client_set_user_context (client, ctx);
1121 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1122}
1123
1124
821struct JoinDecisionClosure 1125struct JoinDecisionClosure
822{ 1126{
823 int32_t is_admitted; 1127 int32_t is_admitted;
@@ -1777,10 +2081,94 @@ static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1777 { &client_recv_state_get, NULL, 2081 { &client_recv_state_get, NULL,
1778 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 }, 2082 GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 },
1779 2083
2084 { &client_recv_place_listen, NULL,
2085 GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN, 0 },
2086
1780 { NULL, NULL, 0, 0 } 2087 { NULL, NULL, 0, 0 }
1781}; 2088};
1782 2089
1783 2090
2091int
2092file_place_load (void *cls, const char *filename)
2093{
2094 uint64_t fsize = 0;
2095 if (GNUNET_OK !=
2096 GNUNET_DISK_file_size (filename, &fsize, GNUNET_YES, GNUNET_YES)
2097 || fsize < sizeof (struct HostEnterRequest))
2098 return GNUNET_OK;
2099
2100 struct GNUNET_MessageHeader *msg = GNUNET_malloc (fsize);
2101 ssize_t rsize = GNUNET_DISK_fn_read (filename, msg, fsize);
2102 if (rsize < 0 || (size_t) rsize < sizeof (*msg))
2103 return GNUNET_OK;
2104
2105 uint16_t msg_size = ntohs (msg->size);
2106 struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub;
2107 struct GNUNET_CRYPTO_EddsaPublicKey place_pub;
2108
2109 switch (ntohs (msg->type))
2110 {
2111 case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER:
2112 if (msg_size < sizeof (struct HostEnterRequest))
2113 return GNUNET_OK;
2114 struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg;
2115 GNUNET_CRYPTO_ecdsa_key_get_public (&hreq->host_key, &ego_pub);
2116 GNUNET_CRYPTO_eddsa_key_get_public (&hreq->place_key, &place_pub);
2117
2118 host_enter (hreq, NULL);
2119 break;
2120
2121 case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER:
2122 if (msg_size < sizeof (struct GuestEnterRequest))
2123 return GNUNET_OK;
2124 struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg;
2125 GNUNET_CRYPTO_ecdsa_key_get_public (&greq->guest_key, &ego_pub);
2126 place_pub = greq->place_key;
2127
2128 guest_enter (greq, NULL);
2129 break;
2130
2131 default:
2132 return GNUNET_OK;
2133 }
2134
2135 struct GNUNET_HashCode ego_pub_hash, place_pub_hash;
2136 GNUNET_CRYPTO_hash (&ego_pub, sizeof (ego_pub), &ego_pub_hash);
2137 GNUNET_CRYPTO_hash (&place_pub, sizeof (place_pub), &place_pub_hash);
2138
2139 place_add (&ego_pub_hash, &place_pub_hash, msg);
2140 return GNUNET_OK;
2141}
2142
2143
2144int
2145load_places_of_ego (void *cls, const char *dir_ego)
2146{
2147 if (GNUNET_YES != GNUNET_DISK_directory_test (dir_ego, GNUNET_YES))
2148 return GNUNET_OK;
2149
2150 GNUNET_DISK_directory_scan (dir_ego, file_place_load, NULL);
2151 return GNUNET_OK;
2152}
2153
2154
2155void
2156load_places ()
2157{
2158 if (GNUNET_OK !=
2159 GNUNET_CONFIGURATION_get_value_filename (cfg, "social", "PLACES_DIR",
2160 &dir_places))
2161 {
2162 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "social", "PLACES_DIR");
2163 GNUNET_break (0);
2164 return;
2165 }
2166
2167 places_entered = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
2168 GNUNET_DISK_directory_scan (dir_places, load_places_of_ego, NULL);
2169}
2170
2171
1784/** 2172/**
1785 * Initialize the PSYC service. 2173 * Initialize the PSYC service.
1786 * 2174 *
@@ -1797,6 +2185,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1797 hosts = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 2185 hosts = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1798 guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 2186 guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
1799 place_guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2187 place_guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
2188 place_listeners = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
2189 load_places ();
2190
1800 nc = GNUNET_SERVER_notification_context_create (server, 1); 2191 nc = GNUNET_SERVER_notification_context_create (server, 1);
1801 GNUNET_SERVER_add_handlers (server, handlers); 2192 GNUNET_SERVER_add_handlers (server, handlers);
1802 GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); 2193 GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
diff --git a/src/social/social.h b/src/social/social.h
index 0a9792b35..6dfd55612 100644
--- a/src/social/social.h
+++ b/src/social/social.h
@@ -24,7 +24,7 @@
24 * @author Gabor X Toth 24 * @author Gabor X Toth
25 */ 25 */
26 26
27#ifndef SOCIAL_H 27#ifndef SOCIAL_H
28#define SOCIAL_H 28#define SOCIAL_H
29 29
30#include "platform.h" 30#include "platform.h"
@@ -85,8 +85,18 @@ struct GuestEnterRequest
85}; 85};
86 86
87 87
88/**** service -> library ****/ 88struct PlaceListenRequest
89{
90 /**
91 * Type: GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN
92 */
93 struct GNUNET_MessageHeader header;
89 94
95 struct GNUNET_CRYPTO_EcdsaPrivateKey ego_key;
96};
97
98
99/**** service -> library ****/
90 100
91#if REMOVE 101#if REMOVE
92struct NymEnterRequest 102struct NymEnterRequest
diff --git a/src/social/social_api.c b/src/social/social_api.c
index 24607bf61..9a2f99ae8 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -1,4 +1,4 @@
1 /* 1/*
2 * This file is part of GNUnet 2 * This file is part of GNUnet
3 * Copyright (C) 2013 Christian Grothoff (and other contributing authors) 3 * Copyright (C) 2013 Christian Grothoff (and other contributing authors)
4 * 4 *
@@ -190,6 +190,19 @@ struct GNUNET_SOCIAL_Guest
190 190
191 191
192/** 192/**
193 * Handle for place notifications.
194 */
195struct GNUNET_SOCIAL_PlaceListenHandle
196{
197 struct GNUNET_SOCIAL_Place plc;
198
199 GNUNET_SOCIAL_PlaceNotifyHostCallback notify_host;
200 GNUNET_SOCIAL_PlaceNotifyGuestCallback notify_guest;
201 void *notify_cls;
202};
203
204
205/**
193 * Hash map of all nyms. 206 * Hash map of all nyms.
194 * pub_key_hash -> struct GNUNET_SOCIAL_Nym * 207 * pub_key_hash -> struct GNUNET_SOCIAL_Nym *
195 */ 208 */
@@ -1275,19 +1288,19 @@ host_recv_enter_request (void *cls,
1275 char *str; 1288 char *str;
1276 const struct GNUNET_PSYC_JoinRequestMessage * 1289 const struct GNUNET_PSYC_JoinRequestMessage *
1277 req = (const struct GNUNET_PSYC_JoinRequestMessage *) msg; 1290 req = (const struct GNUNET_PSYC_JoinRequestMessage *) msg;
1278 const struct GNUNET_PSYC_Message *entry_msg = NULL; 1291 const struct GNUNET_PSYC_Message *join_msg = NULL;
1279 1292
1280 do 1293 do
1281 { 1294 {
1282 if (sizeof (*req) + sizeof (*entry_msg) <= ntohs (req->header.size)) 1295 if (sizeof (*req) + sizeof (*join_msg) <= ntohs (req->header.size))
1283 { 1296 {
1284 entry_msg = (struct GNUNET_PSYC_Message *) &req[1]; 1297 join_msg = (struct GNUNET_PSYC_Message *) &req[1];
1285 LOG (GNUNET_ERROR_TYPE_DEBUG, 1298 LOG (GNUNET_ERROR_TYPE_DEBUG,
1286 "Received entry_msg of type %u and size %u.\n", 1299 "Received join_msg of type %u and size %u.\n",
1287 ntohs (entry_msg->header.type), ntohs (entry_msg->header.size)); 1300 ntohs (join_msg->header.type), ntohs (join_msg->header.size));
1288 1301
1289 env = GNUNET_ENV_environment_create (); 1302 env = GNUNET_ENV_environment_create ();
1290 entry_pmsg = GNUNET_PSYC_message_header_create_from_psyc (entry_msg); 1303 entry_pmsg = GNUNET_PSYC_message_header_create_from_psyc (join_msg);
1291 if (GNUNET_OK != GNUNET_PSYC_message_parse (entry_pmsg, &method_name, env, 1304 if (GNUNET_OK != GNUNET_PSYC_message_parse (entry_pmsg, &method_name, env,
1292 &data, &data_size)) 1305 &data, &data_size))
1293 { 1306 {
@@ -1350,6 +1363,56 @@ guest_recv_join_decision (void *cls,
1350} 1363}
1351 1364
1352 1365
1366static void
1367notify_recv_place_host (void *cls,
1368 struct GNUNET_CLIENT_MANAGER_Connection *client,
1369 const struct GNUNET_MessageHeader *msg)
1370{
1371 struct GNUNET_SOCIAL_PlaceListenHandle *
1372 pl = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*pl));
1373 if (NULL == pl->notify_host)
1374 return;
1375
1376 struct HostEnterRequest *
1377 hreq = (struct HostEnterRequest *) msg;
1378
1379 pl->notify_host (pl->notify_cls, &hreq->place_key, ntohl (hreq->policy));
1380}
1381
1382
1383static void
1384notify_recv_place_guest (void *cls,
1385 struct GNUNET_CLIENT_MANAGER_Connection *client,
1386 const struct GNUNET_MessageHeader *msg)
1387{
1388 struct GNUNET_SOCIAL_PlaceListenHandle *
1389 pl = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*pl));
1390 if (NULL == pl->notify_guest)
1391 return;
1392
1393 struct GuestEnterRequest *
1394 greq = (struct GuestEnterRequest *) msg;
1395 uint16_t greq_size = ntohs (greq->header.size);
1396
1397 const struct GNUNET_PeerIdentity *relays = NULL;
1398 uint16_t relay_count = ntohs (greq->relay_count);
1399 uint16_t relay_size = relay_count * sizeof (*relays);
1400 if (0 < relay_size)
1401 relays = (const struct GNUNET_PeerIdentity *) &greq[1];
1402 struct GNUNET_PSYC_Message *join_msg = NULL;
1403
1404 if (sizeof (*greq) + relay_size + sizeof (struct GNUNET_MessageHeader)
1405 <= greq_size)
1406 {
1407 join_msg = (struct GNUNET_PSYC_Message *)
1408 (((char *) &greq[1]) + relay_size);
1409 }
1410
1411 pl->notify_guest (pl->notify_cls, &greq->place_key, &greq->origin,
1412 relay_count, relays, join_msg);
1413}
1414
1415
1353static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] = 1416static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] =
1354{ 1417{
1355 { host_recv_enter_ack, NULL, 1418 { host_recv_enter_ack, NULL,
@@ -1426,6 +1489,21 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler guest_handlers[] =
1426}; 1489};
1427 1490
1428 1491
1492
1493static struct GNUNET_CLIENT_MANAGER_MessageHandler notify_handlers[] =
1494{
1495 { notify_recv_place_host, NULL,
1496 GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER,
1497 sizeof (struct HostEnterRequest), GNUNET_NO },
1498
1499 { notify_recv_place_guest, NULL,
1500 GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER,
1501 sizeof (struct GuestEnterRequest), GNUNET_YES },
1502
1503 { NULL, NULL, 0, 0, GNUNET_NO }
1504};
1505
1506
1429static void 1507static void
1430place_cleanup (struct GNUNET_SOCIAL_Place *plc) 1508place_cleanup (struct GNUNET_SOCIAL_Place *plc)
1431{ 1509{
@@ -1533,13 +1611,6 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1533 GNUNET_free (ephemeral_key); 1611 GNUNET_free (ephemeral_key);
1534 } 1612 }
1535 1613
1536 req->header.size = htons (sizeof (*req));
1537 req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER);
1538 req->policy = policy;
1539 req->place_key = hst->place_key;
1540 req->host_key = plc->ego_key;
1541
1542 plc->connect_msg = (struct GNUNET_MessageHeader *) req;
1543 plc->cfg = cfg; 1614 plc->cfg = cfg;
1544 plc->is_host = GNUNET_YES; 1615 plc->is_host = GNUNET_YES;
1545 plc->slicer = slicer; 1616 plc->slicer = slicer;
@@ -1565,7 +1636,15 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1565 NULL, host_recv_notice_place_leave_eom, hst); 1636 NULL, host_recv_notice_place_leave_eom, hst);
1566 hst->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, hst->slicer); 1637 hst->recv = GNUNET_PSYC_receive_create (NULL, slicer_message, hst->slicer);
1567 1638
1639 req->header.size = htons (sizeof (*req));
1640 req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER);
1641 req->policy = policy;
1642 req->place_key = hst->place_key;
1643 req->host_key = plc->ego_key;
1644
1645 plc->connect_msg = (struct GNUNET_MessageHeader *) req;
1568 place_send_connect_msg (plc); 1646 place_send_connect_msg (plc);
1647
1569 return hst; 1648 return hst;
1570} 1649}
1571 1650
@@ -1972,7 +2051,7 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1972 const struct GNUNET_PeerIdentity *origin, 2051 const struct GNUNET_PeerIdentity *origin,
1973 uint32_t relay_count, 2052 uint32_t relay_count,
1974 const struct GNUNET_PeerIdentity *relays, 2053 const struct GNUNET_PeerIdentity *relays,
1975 const struct GNUNET_PSYC_Message *entry_msg, 2054 const struct GNUNET_PSYC_Message *join_msg,
1976 struct GNUNET_SOCIAL_Slicer *slicer, 2055 struct GNUNET_SOCIAL_Slicer *slicer,
1977 GNUNET_SOCIAL_GuestEnterCallback local_enter_cb, 2056 GNUNET_SOCIAL_GuestEnterCallback local_enter_cb,
1978 GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb, 2057 GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb,
@@ -1999,7 +2078,7 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
1999 2078
2000 struct GuestEnterRequest * 2079 struct GuestEnterRequest *
2001 req = guest_enter_request_create (&plc->ego_key, place_key, origin, 2080 req = guest_enter_request_create (&plc->ego_key, place_key, origin,
2002 relay_count, relays, entry_msg); 2081 relay_count, relays, join_msg);
2003 plc->connect_msg = &req->header; 2082 plc->connect_msg = &req->header;
2004 place_send_connect_msg (plc); 2083 place_send_connect_msg (plc);
2005 return gst; 2084 return gst;
@@ -2200,7 +2279,7 @@ GNUNET_SOCIAL_guest_talk_resume (struct GNUNET_SOCIAL_TalkRequest *tr)
2200void 2279void
2201GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) 2280GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr)
2202{ 2281{
2203 GNUNET_PSYC_transmit_cancel ((struct GNUNET_PSYC_TransmitHandle *) tr); 2282 GNUNET_PSYC_transmit_cancel ( (struct GNUNET_PSYC_TransmitHandle *) tr);
2204} 2283}
2205 2284
2206 2285
@@ -2501,8 +2580,8 @@ GNUNET_SOCIAL_place_look_cancel (struct GNUNET_SOCIAL_LookHandle *look)
2501 * Ego. 2580 * Ego.
2502 * @param name 2581 * @param name
2503 * The name for the PKEY record to put in the zone. 2582 * The name for the PKEY record to put in the zone.
2504 * @param pub_key 2583 * @param nym_pub_key
2505 * Public key to add. 2584 * Public key of nym to add.
2506 * @param expiration_time 2585 * @param expiration_time
2507 * Expiration time of the record, use 0 to remove the record. 2586 * Expiration time of the record, use 0 to remove the record.
2508 * @param result_cb 2587 * @param result_cb
@@ -2514,7 +2593,7 @@ void
2514GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg, 2593GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg,
2515 const struct GNUNET_IDENTITY_Ego *ego, 2594 const struct GNUNET_IDENTITY_Ego *ego,
2516 const char *name, 2595 const char *name,
2517 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key, 2596 const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key,
2518 struct GNUNET_TIME_Absolute expiration_time, 2597 struct GNUNET_TIME_Absolute expiration_time,
2519 GNUNET_NAMESTORE_ContinuationWithStatus result_cb, 2598 GNUNET_NAMESTORE_ContinuationWithStatus result_cb,
2520 void *result_cls) 2599 void *result_cls)
@@ -2526,8 +2605,8 @@ GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg,
2526 rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; 2605 rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
2527 rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; 2606 rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
2528 rd.expiration_time = expiration_time.abs_value_us; 2607 rd.expiration_time = expiration_time.abs_value_us;
2529 rd.data = pub_key; 2608 rd.data = nym_pub_key;
2530 rd.data_size = sizeof (*pub_key); 2609 rd.data_size = sizeof (*nym_pub_key);
2531 2610
2532 GNUNET_NAMESTORE_records_store (namestore, 2611 GNUNET_NAMESTORE_records_store (namestore,
2533 GNUNET_IDENTITY_ego_get_private_key (ego), 2612 GNUNET_IDENTITY_ego_get_private_key (ego),
@@ -2535,4 +2614,68 @@ GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg,
2535} 2614}
2536 2615
2537 2616
2617/**
2618 * Start listening for entered places as host or guest.
2619 *
2620 * The @notify_host and @notify_guest functions are
2621 * initially called with the full list of entered places,
2622 * then later each time a new place is entered.
2623 *
2624 * @param cfg
2625 * Configuration.
2626 * @param ego
2627 * Listen for places of this ego.
2628 * @param notify_host
2629 * Function to notify about a place entered as host.
2630 * @param notify_guest
2631 * Function to notify about a place entered as guest..
2632 * @param notify_cls
2633 * Closure for the callbacks.
2634 *
2635 * @return Handle that can be used to stop listening.
2636 */
2637struct GNUNET_SOCIAL_PlaceListenHandle *
2638GNUNET_SOCIAL_place_listen_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
2639 const struct GNUNET_IDENTITY_Ego *ego,
2640 GNUNET_SOCIAL_PlaceNotifyHostCallback notify_host,
2641 GNUNET_SOCIAL_PlaceNotifyGuestCallback notify_guest,
2642 void *notify_cls)
2643{
2644 struct GNUNET_SOCIAL_PlaceListenHandle *pl = GNUNET_malloc (sizeof *pl);
2645 pl->notify_host = notify_host;
2646 pl->notify_guest = notify_guest;
2647 pl->notify_cls = notify_cls;
2648
2649 struct GNUNET_SOCIAL_Place *plc = &pl->plc;
2650
2651 plc->ego_key = *GNUNET_IDENTITY_ego_get_private_key (ego);
2652 plc->cfg = cfg;
2653 plc->client = GNUNET_CLIENT_MANAGER_connect (cfg, "social",
2654 notify_handlers);
2655 GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, pl, sizeof (*pl));
2656
2657 struct PlaceListenRequest *req = GNUNET_malloc (sizeof (*req));
2658 req->ego_key = plc->ego_key;
2659 req->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LISTEN);
2660 req->header.size = htons (sizeof (*req));
2661
2662 plc->connect_msg = (struct GNUNET_MessageHeader *) req;
2663 place_send_connect_msg (plc);
2664
2665 return pl;
2666}
2667
2668
2669/**
2670 * Stop listening for entered places.
2671 *
2672 * @param pl
2673 * Place listen handle.
2674 */
2675void
2676GNUNET_SOCIAL_place_listen_stop (struct GNUNET_SOCIAL_PlaceListenHandle *pl)
2677{
2678 GNUNET_CLIENT_MANAGER_disconnect (pl->plc.client, GNUNET_NO, NULL, NULL);
2679}
2680
2538/* end of social_api.c */ 2681/* end of social_api.c */
diff --git a/src/social/test_social.c b/src/social/test_social.c
index d070ecf69..158fa469d 100644
--- a/src/social/test_social.c
+++ b/src/social/test_social.c
@@ -300,6 +300,8 @@ host_left ()
300 hst = NULL; 300 hst = NULL;
301 hst_plc = NULL; 301 hst_plc = NULL;
302 302
303 // TODO: GNUNET_SOCIAL_place_listen_start ()
304
303 end (); 305 end ();
304} 306}
305 307