diff options
author | Gabor X Toth <*@tg-x.net> | 2015-11-18 22:13:27 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2015-11-18 22:13:27 +0000 |
commit | ad0201797ed84806a0a42fe3435dd56bd2c69ae5 (patch) | |
tree | 83a04545e9d8dc1799892ca6c37b3af083b0e7bd /src/social | |
parent | aba4cac0f08ecb17df34e375337090b00f457763 (diff) | |
download | gnunet-ad0201797ed84806a0a42fe3435dd56bd2c69ae5.tar.gz gnunet-ad0201797ed84806a0a42fe3435dd56bd2c69ae5.zip |
social: store/load entered places & notify clients about them
Diffstat (limited to 'src/social')
-rw-r--r-- | src/social/gnunet-service-social.c | 499 | ||||
-rw-r--r-- | src/social/social.h | 14 | ||||
-rw-r--r-- | src/social/social_api.c | 187 | ||||
-rw-r--r-- | src/social/test_social.c | 2 |
4 files changed, 624 insertions, 78 deletions
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 | */ |
59 | static struct GNUNET_CONTAINER_MultiHashMap *hosts; | 59 | static 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 | */ |
65 | static struct GNUNET_CONTAINER_MultiHashMap *guests; | 65 | static 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 | */ |
71 | static struct GNUNET_CONTAINER_MultiHashMap *place_guests; | 71 | static 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 | */ | ||
77 | static struct GNUNET_CONTAINER_MultiHashMap *places_entered; | ||
78 | |||
79 | /** | ||
80 | * Place listener clients. | ||
81 | * H(ego_pub_key) -> struct PlaceListener | ||
82 | */ | ||
83 | static struct GNUNET_CONTAINER_MultiHashMap *place_listeners; | ||
84 | |||
85 | /** | ||
86 | * Directory for storing places. | ||
87 | */ | ||
88 | static 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 | */ | ||
278 | struct Client | 298 | struct 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 | |||
318 | struct 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 | */ | ||
672 | static int | ||
673 | place_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 | */ |
628 | static void | 721 | static void |
629 | client_recv_host_enter (void *cls, struct GNUNET_SERVER_Client *client, | 722 | place_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 | */ | ||
777 | static int | ||
778 | host_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 | */ | ||
820 | static void | ||
821 | client_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 | */ |
699 | static void | 886 | static int |
700 | client_recv_guest_enter (void *cls, struct GNUNET_SERVER_Client *client, | 887 | guest_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 | */ | ||
978 | static void | ||
979 | client_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 | ||
1037 | void | ||
1038 | place_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 | |||
1074 | int | ||
1075 | map_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 | */ | ||
1085 | static void | ||
1086 | client_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 | |||
821 | struct JoinDecisionClosure | 1125 | struct 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 | ||
2091 | int | ||
2092 | file_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 | |||
2144 | int | ||
2145 | load_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 | |||
2155 | void | ||
2156 | load_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 ****/ | 88 | struct 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 |
92 | struct NymEnterRequest | 102 | struct 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 | */ | ||
195 | struct 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 | ||
1366 | static void | ||
1367 | notify_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 | |||
1383 | static void | ||
1384 | notify_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 | |||
1353 | static struct GNUNET_CLIENT_MANAGER_MessageHandler host_handlers[] = | 1416 | static 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 | |||
1493 | static 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 | |||
1429 | static void | 1507 | static void |
1430 | place_cleanup (struct GNUNET_SOCIAL_Place *plc) | 1508 | place_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) | |||
2200 | void | 2279 | void |
2201 | GNUNET_SOCIAL_guest_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr) | 2280 | GNUNET_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 | |||
2514 | GNUNET_SOCIAL_zone_add_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg, | 2593 | GNUNET_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 | */ | ||
2637 | struct GNUNET_SOCIAL_PlaceListenHandle * | ||
2638 | GNUNET_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 | */ | ||
2675 | void | ||
2676 | GNUNET_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 | ||