aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo/gnunet-service-peerinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/peerinfo/gnunet-service-peerinfo.c')
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c178
1 files changed, 120 insertions, 58 deletions
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c
index 7475ee34f..04ced7d17 100644
--- a/src/peerinfo/gnunet-service-peerinfo.c
+++ b/src/peerinfo/gnunet-service-peerinfo.c
@@ -67,8 +67,49 @@ struct HostEntry
67 67
68}; 68};
69 69
70/**
71 * Transmit context for GET requests
72 */
73struct TransmitContext
74{
75 /**
76 * Server transmit context
77 */
78 struct GNUNET_SERVER_TransmitContext *tc;
79
80 /**
81 * Include friend only HELLOs GNUNET_YES or _NO
82 */
83 int friend_only;
84};
70 85
71 86
87/**
88 * Client notification context
89 */
90struct NotificationContext
91{
92 /**
93 * Next in DLL
94 */
95 struct NotificationContext *prev;
96
97 /**
98 * Previous in DLL
99 */
100 struct NotificationContext *next;
101
102 /**
103 * Server client
104 */
105 struct GNUNET_SERVER_Client *client;
106
107 /**
108 * Interested in friend only HELLO?
109 */
110 int include_friend_only;
111};
112
72 113
73/** 114/**
74 * The in-memory list of known hosts, mapping of 115 * The in-memory list of known hosts, mapping of
@@ -82,11 +123,6 @@ static struct GNUNET_CONTAINER_MultiHashMap *hostmap;
82static struct GNUNET_SERVER_NotificationContext *notify_list; 123static struct GNUNET_SERVER_NotificationContext *notify_list;
83 124
84/** 125/**
85 * Clients to immediately notify about all changes.
86 */
87static struct GNUNET_SERVER_NotificationContext *notify_friend_only_list;
88
89/**
90 * Directory where the hellos are stored in (data/hosts) 126 * Directory where the hellos are stored in (data/hosts)
91 */ 127 */
92static char *networkIdDirectory; 128static char *networkIdDirectory;
@@ -96,6 +132,15 @@ static char *networkIdDirectory;
96 */ 132 */
97static struct GNUNET_STATISTICS_Handle *stats; 133static struct GNUNET_STATISTICS_Handle *stats;
98 134
135/**
136 * DLL of notification contexts: head
137 */
138static struct NotificationContext *nc_head;
139
140/**
141 * DLL of notification contexts: tail
142 */
143static struct NotificationContext *nc_tail;
99 144
100 145
101/** 146/**
@@ -197,23 +242,22 @@ static void
197notify_all (struct HostEntry *entry) 242notify_all (struct HostEntry *entry)
198{ 243{
199 struct InfoMessage *msg; 244 struct InfoMessage *msg;
245 struct NotificationContext *cur;
200 246
201 msg = make_info_message (entry); 247 msg = make_info_message (entry);
202 if ((NULL != entry->hello) && 248
203 (GNUNET_YES == GNUNET_HELLO_is_friend_only(entry->hello))) 249 for (cur = nc_head; NULL != cur; cur = cur->next)
204 { 250 {
205 GNUNET_SERVER_notification_context_broadcast (notify_friend_only_list, 251 if ((NULL != entry->hello) &&
206 &msg->header, 252 (GNUNET_YES == GNUNET_HELLO_is_friend_only (entry->hello)) &&
207 GNUNET_NO); 253 (GNUNET_NO == cur->include_friend_only))
208 } 254 continue; /* Friend only HELLO this client should not get */
209 else 255
210 { 256 GNUNET_SERVER_notification_context_unicast (notify_list,
211 GNUNET_SERVER_notification_context_broadcast (notify_friend_only_list, 257 cur->client,
212 &msg->header, 258 &msg->header,
213 GNUNET_NO); 259 GNUNET_NO);
214 GNUNET_SERVER_notification_context_broadcast (notify_list, &msg->header, 260 }
215 GNUNET_NO);
216 }
217 GNUNET_free (msg); 261 GNUNET_free (msg);
218} 262}
219 263
@@ -511,15 +555,6 @@ bind_address (const struct GNUNET_PeerIdentity *peer,
511} 555}
512 556
513 557
514struct TransmitContext
515{
516 struct GNUNET_SERVER_TransmitContext *tc;
517
518 int friend_only;
519};
520
521
522
523/** 558/**
524 * Do transmit info about peer to given host. 559 * Do transmit info about peer to given host.
525 * 560 *
@@ -650,7 +685,7 @@ handle_hello (void *cls, struct GNUNET_SERVER_Client *client,
650 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 685 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
651 return; 686 return;
652 } 687 }
653 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received for peer `%4s'\n", 688 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "`%s' message received for peer `%4s'\n",
654 "HELLO", GNUNET_i2s (&pid)); 689 "HELLO", GNUNET_i2s (&pid));
655 bind_address (&pid, hello); 690 bind_address (&pid, hello);
656 GNUNET_SERVER_receive_done (client, GNUNET_OK); 691 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -708,13 +743,6 @@ handle_get_all (void *cls, struct GNUNET_SERVER_Client *client,
708 GNUNET_SERVER_transmit_context_run (tcx.tc, GNUNET_TIME_UNIT_FOREVER_REL); 743 GNUNET_SERVER_transmit_context_run (tcx.tc, GNUNET_TIME_UNIT_FOREVER_REL);
709} 744}
710 745
711struct NotificationContext
712{
713 struct GNUNET_SERVER_Client *client;
714
715 int friend_only;
716};
717
718 746
719/** 747/**
720 * Pass the given client the information we have in the respective 748 * Pass the given client the information we have in the respective
@@ -732,18 +760,24 @@ do_notify_entry (void *cls, const struct GNUNET_HashCode * key, void *value)
732 struct HostEntry *he = value; 760 struct HostEntry *he = value;
733 struct InfoMessage *msg; 761 struct InfoMessage *msg;
734 762
735 if ((NULL != he->hello) && 763 if ((NULL != he->hello) &&
736 (GNUNET_YES == GNUNET_HELLO_is_friend_only(he->hello)) && 764 (GNUNET_YES == GNUNET_HELLO_is_friend_only(he->hello)) &&
737 (GNUNET_NO == nc->friend_only)) 765 (GNUNET_NO == nc->include_friend_only))
738 return GNUNET_YES; 766 {
739 767 /* We have a friend only hello and a client not interested, continue */
740 msg = make_info_message (he); 768 return GNUNET_YES;
741 GNUNET_SERVER_notification_context_unicast (notify_list, nc->client, &msg->header, 769 }
742 GNUNET_NO); 770
771 msg = make_info_message (he);
772 GNUNET_SERVER_notification_context_unicast (notify_list,
773 nc->client,
774 &msg->header,
775 GNUNET_NO);
743 GNUNET_free (msg); 776 GNUNET_free (msg);
744 return GNUNET_YES; 777 return GNUNET_YES;
745} 778}
746 779
780
747/** 781/**
748 * Handle NOTIFY-message. 782 * Handle NOTIFY-message.
749 * 783 *
@@ -756,25 +790,45 @@ handle_notify (void *cls, struct GNUNET_SERVER_Client *client,
756 const struct GNUNET_MessageHeader *message) 790 const struct GNUNET_MessageHeader *message)
757{ 791{
758 struct NotifyMessage *nm = (struct NotifyMessage *) message; 792 struct NotifyMessage *nm = (struct NotifyMessage *) message;
759 struct NotificationContext nc; 793 struct NotificationContext *nc;
760 int friend_only;
761 794
762 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "NOTIFY"); 795 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "NOTIFY");
763 796
764 nc.client = client; 797 nc = GNUNET_malloc (sizeof (struct NotificationContext));
765 nc.friend_only = ntohl (nm->include_friend_only); 798 nc->client = client;
799 nc->include_friend_only = ntohl (nm->include_friend_only);
766 800
801 GNUNET_CONTAINER_DLL_insert (nc_head, nc_tail, nc);
767 GNUNET_SERVER_client_mark_monitor (client); 802 GNUNET_SERVER_client_mark_monitor (client);
768 if (GNUNET_YES == ntohl (nm->include_friend_only)) 803 GNUNET_SERVER_notification_context_add (notify_list, client);
769 GNUNET_SERVER_notification_context_add (notify_friend_only_list, client); 804 GNUNET_CONTAINER_multihashmap_iterate (hostmap, &do_notify_entry, nc);
770 else
771 GNUNET_SERVER_notification_context_add (notify_list, client);
772 GNUNET_CONTAINER_multihashmap_iterate (hostmap, &do_notify_entry, &nc);
773 GNUNET_SERVER_receive_done (client, GNUNET_OK); 805 GNUNET_SERVER_receive_done (client, GNUNET_OK);
774} 806}
775 807
776 808
777/** 809/**
810 * Client disconnect callback
811 *
812 * @param cls unused
813 * @param client server client
814 */
815static void disconnect_cb (void *cls,struct GNUNET_SERVER_Client *client)
816{
817 struct NotificationContext *cur;
818
819 for (cur = nc_head; NULL != cur; cur = cur->next)
820 if (cur->client == client)
821 break;
822
823 if (NULL == cur)
824 return;
825
826 GNUNET_CONTAINER_DLL_remove (nc_head, nc_tail, cur);
827 GNUNET_free (cur);
828}
829
830
831/**
778 * Release memory taken by a host entry. 832 * Release memory taken by a host entry.
779 * 833 *
780 * @param cls NULL 834 * @param cls NULL
@@ -802,10 +856,18 @@ free_host_entry (void *cls, const struct GNUNET_HashCode * key, void *value)
802static void 856static void
803shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 857shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
804{ 858{
805 GNUNET_SERVER_notification_context_destroy (notify_list); 859 struct NotificationContext *cur;
860 struct NotificationContext *next;
861 GNUNET_SERVER_notification_context_destroy (notify_list);
806 notify_list = NULL; 862 notify_list = NULL;
807 GNUNET_SERVER_notification_context_destroy (notify_friend_only_list); 863
808 notify_friend_only_list = NULL; 864 for (cur = nc_head; NULL != cur; cur = next)
865 {
866 next = cur->next;
867 GNUNET_CONTAINER_DLL_remove (nc_head, nc_tail, cur);
868 GNUNET_free (cur);
869 }
870
809 GNUNET_CONTAINER_multihashmap_iterate (hostmap, &free_host_entry, NULL); 871 GNUNET_CONTAINER_multihashmap_iterate (hostmap, &free_host_entry, NULL);
810 GNUNET_CONTAINER_multihashmap_destroy (hostmap); 872 GNUNET_CONTAINER_multihashmap_destroy (hostmap);
811 if (NULL != stats) 873 if (NULL != stats)
@@ -845,7 +907,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
845 hostmap = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES); 907 hostmap = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES);
846 stats = GNUNET_STATISTICS_create ("peerinfo", cfg); 908 stats = GNUNET_STATISTICS_create ("peerinfo", cfg);
847 notify_list = GNUNET_SERVER_notification_context_create (server, 0); 909 notify_list = GNUNET_SERVER_notification_context_create (server, 0);
848 notify_friend_only_list = GNUNET_SERVER_notification_context_create (server, 0);
849 noio = GNUNET_CONFIGURATION_get_value_yesno (cfg, "peerinfo", "NO_IO"); 910 noio = GNUNET_CONFIGURATION_get_value_yesno (cfg, "peerinfo", "NO_IO");
850 if (GNUNET_YES != noio) 911 if (GNUNET_YES != noio)
851 { 912 {
@@ -873,6 +934,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
873 GNUNET_free (peerdir); 934 GNUNET_free (peerdir);
874 } 935 }
875 GNUNET_SERVER_add_handlers (server, handlers); 936 GNUNET_SERVER_add_handlers (server, handlers);
937 GNUNET_SERVER_disconnect_notify (server, &disconnect_cb, NULL) ;
876 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 938 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
877 NULL); 939 NULL);
878 940