diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-04-05 08:51:34 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-04-05 08:51:34 +0000 |
commit | e3daa8dfbdc25878982de09ef391ea39929c5184 (patch) | |
tree | acc7901cbb659ebf32afa18394c322abba0f6fac /src | |
parent | b7666e100947208ec7d3580e6b4f16ae196c9bab (diff) | |
download | gnunet-e3daa8dfbdc25878982de09ef391ea39929c5184.tar.gz gnunet-e3daa8dfbdc25878982de09ef391ea39929c5184.zip |
fixed client notifications
Diffstat (limited to 'src')
-rw-r--r-- | src/peerinfo/gnunet-service-peerinfo.c | 178 |
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 | */ | ||
73 | struct 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 | */ | ||
90 | struct 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; | |||
82 | static struct GNUNET_SERVER_NotificationContext *notify_list; | 123 | static struct GNUNET_SERVER_NotificationContext *notify_list; |
83 | 124 | ||
84 | /** | 125 | /** |
85 | * Clients to immediately notify about all changes. | ||
86 | */ | ||
87 | static 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 | */ |
92 | static char *networkIdDirectory; | 128 | static char *networkIdDirectory; |
@@ -96,6 +132,15 @@ static char *networkIdDirectory; | |||
96 | */ | 132 | */ |
97 | static struct GNUNET_STATISTICS_Handle *stats; | 133 | static struct GNUNET_STATISTICS_Handle *stats; |
98 | 134 | ||
135 | /** | ||
136 | * DLL of notification contexts: head | ||
137 | */ | ||
138 | static struct NotificationContext *nc_head; | ||
139 | |||
140 | /** | ||
141 | * DLL of notification contexts: tail | ||
142 | */ | ||
143 | static struct NotificationContext *nc_tail; | ||
99 | 144 | ||
100 | 145 | ||
101 | /** | 146 | /** |
@@ -197,23 +242,22 @@ static void | |||
197 | notify_all (struct HostEntry *entry) | 242 | notify_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 | ||
514 | struct 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 | ||
711 | struct 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 | */ | ||
815 | static 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) | |||
802 | static void | 856 | static void |
803 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 857 | shutdown_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 | ||